﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network.GameClient;
using Rappelz.GameServer.Network;
using System.Threading;
using Rappelz.GameServer.Database;

namespace Rappelz.GameServer
{
    public class Creature : GameObject
    {
        public class procStateAddStateInfo
        {
            public State.StateCode code;                // 0x0
            public int nLevel;                          // 0x4
            public uint nEndTime;                       // 0x8
            public int nHate;                           // 0xC
            public Creature pTarget;                    // 0x10

        }

        public class AddStateTag
        {
            public AddStateTag(State.StateCode _code, int _level, int _percentage, uint _duration)
            {
                code = _code;
                level = _level;
                percentage = _percentage;
                duration = _duration;
            }

            public State.StateCode code;
            public int level;
            public int percentage;
            public uint duration;
        }

        public class QuadTreeItem
        {
            // Function       :     public int GetQuadX()
            // Function       :     public int GetQuadY()
            // Function       :     public bool operator==(const struct StructCreature::QuadTreeItem &)
            // Function       :     public void Set(float, float)
            public void Set(Creature c)
            {
                this.parent = c;
                this.x = (int)((parent.mv.x + 3.0) / 6.0);
                this.y = (int)((parent.mv.y + 3.0) / 6.0);
            }

            public static bool IsCanAdd(float x, float y)
            {
                bool result;

                if (GameContent.g_pQuadScanner != null)
                {
                    result = !GameContent.g_pQuadScanner.IsExist(((x + 3.0f) / 6.0f), ((y + 3.0f) / 6.0f));
                }
                else
                {
                    result = true;
                }
                return result;
            }

            public void AddMe()
            {
                this.x = (int)((parent.mv.x + 3.0) / 6.0);
                this.y = (int)((parent.mv.y + 3.0) / 6.0);
                if (GameContent.g_pQuadScanner != null)
                    GameContent.g_pQuadScanner.Add(this);
            }
            
            public bool RemoveMe()
            {
                bool result;

                if (GameContent.g_pQuadScanner != null)
                    result = GameContent.g_pQuadScanner.Remove(this);
                else
                    result = true;
                return result;
            }
            // Function       :     private static int getX(float)
            // Function       :     private static int getY(float)
            public Creature parent;                                     // 0x0
            public int x;                                               // 0x4
            public int y;                                               // 0x8
        }

        public class StateMod
        {
            public StateMod()
            {
                fDamage = 1.0f;
                nDamage = 0;
                fCritical = 1.0f;
                nCritical = 0;
                fHate = 1.0f;
            }

            public StateMod(StateMod src)
            {
                this.fDamage = src.fDamage;
                this.nDamage = src.nDamage;
                this.fCritical = src.fCritical;
                this.nCritical = src.nCritical;
                this.fHate = src.fHate;
            }

            public void Init()
            {

            }

            public void Copy(StateMod src)
            {
                this.fDamage = src.fDamage;
                this.nDamage = src.nDamage;
                this.fCritical = src.fCritical;
                this.nCritical = src.nCritical;
                this.fHate = src.fHate;
            }

            public float fDamage;
            public int nDamage;
            public float fCritical;
            public int nCritical;
            public float fHate;
        }

        public class DamageAbsorbTag
        {
            public DamageAbsorbTag(int _r, float _h, float _m)
            {
                ratio = _r;
                hp_absorb_ratio = _h;
                mp_absorb_ratio = _m;
            }

            public int ratio;
            public float hp_absorb_ratio;
            public float mp_absorb_ratio;
        }

        public class HealOnAttackTag
        {
            public HealOnAttackTag(int r, int h, int m)
            {
                ratio = r;
                hp_inc = h;
                mp_inc = m;
            }

            public int ratio;
            public int hp_inc;
            public int mp_inc;
        }

        public class StealOnAttackTag
        {
            public StealOnAttackTag(int r, int h, int m)
            {
                ratio = r;
                hp_steal = h;
                mp_steal = m;
            }

            public int ratio;
            public int hp_steal;
            public int mp_steal;
        }

        public class ExpertMod
        {
            public float fAvoid;
            public float fDamage;

            public void Reset(float v)
            {
                fAvoid = v;
                fDamage = v;
            }
        }

        public class ElementalSkillStateMod
        {
            // Function       :     public void ElementalSkillStateMod(const struct StructCreature::ElementalSkillStateMod &)
            // Function       :     public void StructCreature::ElementalSkillStateMod::ElementalSkillStateMod()
            public void Init()
            {
                fMagicalDamage = 1.0f;
                fPhysicalDamage = 1.0f;
                fCooltime = 1.0f;
                fCastingSpeed = 1.0f;
                fHate = 1.0f;
                nElementalType = 0;
                fManaCostRatio = 1.0f;
                nMagicalAccuracy = 0;
                nPhysicalAccuracy = 0;
                nCritical = 0;
                vExhaustiveStateCode.Clear();
                nCastingSpeedApplyTime = 0;
            }

            public float fManaCostRatio;
            public float fCooltime;
            public float fCastingSpeed;
            public float fHate;
            public int nMagicalAccuracy;
            public int nPhysicalAccuracy;
            public int nCritical;
            public float fMagicalDamage;
            public float fPhysicalDamage;
            public int nElementalType;
            public uint nCastingSpeedApplyTime;
            public List<State.StateCode> vExhaustiveStateCodeForDelete = new List<State.StateCode>();
            public List<State.StateCode> vExhaustiveStateCode = new List<State.StateCode>();

            // Function       :     public void StructCreature::ElementalSkillStateMod::~ElementalSkillStateMod()
            // Function       :     public struct StructCreature::ElementalSkillStateMod & operator=(const struct StructCreature::ElementalSkillStateMod &)
            // Function       :     public void * __vecDelDtor(unsigned int)
        }

        public class HateModifier
        {
            // Function       :     public void StructCreature::HateModifier::HateModifier(int, int, float, int)
            public bool bIsApplyToPhysicalSkill;
            public bool bIsApplyToMagicalSkill;
            public bool bIsApplyToPhysicalAttack;
            public bool bIsApplyToHarmful;
            public bool bIsApplyToHelpful;
            public float fAmpValue;
            public int nIncValue;
        }

        public class AdditionalDamageInfo
        {
            public AdditionalDamageInfo(byte _ratio, Elemental.Type _require_type, Elemental.Type _type, ushort _nDamage, float _fDamage)
            {
                ratio = _ratio;
                require_type = _require_type;
                type = _type;
                nDamage = _nDamage;
                fDamage = _fDamage;
            }

            public AdditionalDamageInfo(byte _ratio, Elemental.Type _require_type, Elemental.Type _type, float _fDamage)
            {
                ratio = _ratio;
                require_type = _require_type;
                type = _type;
                nDamage = (ushort)_fDamage;
                fDamage = _fDamage;
            }

            public byte ratio;
            public Elemental.Type require_type;
            public Elemental.Type type;
            public ushort nDamage;
            public float fDamage;

        }

        public class DamageReflectInfo
        {
            // Function       :     public void StructCreature::DamageReflectInfo::DamageReflectInfo(unsigned char, float, enum Elemental::Type, unsigned short, float, float, float, bool)
            public byte fire_ratio;
            public float range;
            public Elemental.Type type;
            public ushort nReflectDamage;
            public float fPhysicalReflectRatio;
            public float fPhysicalSkillReflectRatio;
            public float fMagicalReflectRatio;
            public bool bIgnoreDefence;
        }
        
        public class StateReflectInfo
        {
            // Function       :     public void StateReflectInfo(enum StructState::StateCode, int, unsigned long)
            public State.StateCode nCode;
            public int nLevel;
            public uint nDuration;
        }

        public class AddHPMPOnCriticalInfo
        {
            // Function       :     public void AddHPMPOnCriticalInfo(int, int, int)
            public int nAddHP;
            public int nAddMP;
            public int nActivationRate;
        }

        public class DamageReduceInfo
        {
            // Function       :     public void StructCreature::DamageReduceInfo::DamageReduceInfo(unsigned char, float, float, float, int, int, int, int, int)
            public bool IsAppliableCreatureGroup(int creature_group)
            {
                return this.apply_creature_group_list[0] == 99 || this.apply_creature_group_list[0] == creature_group
                    || this.apply_creature_group_list[1] == 99 || this.apply_creature_group_list[1] == creature_group
                    || this.apply_creature_group_list[2] == 99 || this.apply_creature_group_list[2] == creature_group
                    || this.apply_creature_group_list[3] == 99 || this.apply_creature_group_list[3] == creature_group
                    || this.apply_creature_group_list[4] == 99 || this.apply_creature_group_list[4] == creature_group; 
            }
            
            public byte ratio;
            public float physical_reduce;
            public float physical_skill_reduce;
            public float magical_skill_reduce;
            public int[] apply_creature_group_list = new int[5];
        }

        public class Damage
        {
            // UserDefinedType:   _DAMAGE
            // Function       :     public void _DAMAGE()
            public int nDamage;
            public int nResistedDamage;
            public bool bCritical;
            public bool bMiss;
            public bool bBlock;
            public bool bPerfectBlock;
            public int target_hp;
        }

        public class DamageInfo : Damage
        {
            // Function       :     public void StructCreature::_DAMAGE_INFO::_DAMAGE_INFO()
            public void SetDamage(Damage damage)
            {
                this.nDamage = damage.nDamage;
                this.bCritical = damage.bCritical;
                this.bMiss = damage.bMiss;
                this.bBlock = damage.bBlock;
                this.bPerfectBlock = damage.bPerfectBlock;
                this.target_hp = damage.target_hp;
            }

            public ushort[] elemental_damage = new ushort[7];
        }

        public class AttackInfo : DamageInfo
        {
            // Function       :     public void StructCreature::_ATTACK_INFO::_ATTACK_INFO()
            public void SetDamageInfo(DamageInfo damage_info)
            {

                base.SetDamage(damage_info);
                this.elemental_damage[0] = damage_info.elemental_damage[0];
                this.elemental_damage[1] = damage_info.elemental_damage[1];
                this.elemental_damage[2] = damage_info.elemental_damage[2];
                this.elemental_damage[3] = damage_info.elemental_damage[3];
                this.elemental_damage[4] = damage_info.elemental_damage[4];
                this.elemental_damage[5] = damage_info.elemental_damage[5];
                this.elemental_damage[6] = damage_info.elemental_damage[6];
            }


            public short mp_damage;
            public short attacker_damage;
            public short attacker_mp_damage;
            public ushort target_mp;
            public uint attacker_hp;
            public ushort attacker_mp;
        }

        public static int s_nMaxSkillUID;


        public enum StatusFlags : uint
        {
            LoginComplete = 0x01,
            FirstEnter = 0x02,
            AttackStarted = 0x04,
            FirsAttack = 0x08,
            MovePending = 0x10,
            NeedToUpdateState = 0x20,
            MovingByFear = 0x40,
            NeedToCalculateStat = 0x80,
            ProcessingReflect = 0x100,
            Invisible = 0x200,
            Invincible = 0x400,
            Hiding = 0x800,
            Movable = 0x2000,
            Attackable = 0x4000,
            SkillCastable = 0x8000,
            MagicCastable = 0x10000,
            ItemUsable = 0x20000,
            Mortal = 0x40000,
            HavocBurst = 0x80000,
            Feared = 0x100000,
            FormChanged = 0x200000,
            MoveSpeedFixed = 0x400000,
            HPRegenStopped = 0x800000,
            MPRegenStopped = 0x1000000,
            UsingDoubleWeapon = 0x2000000,
            CompeteDead = 0x4000000,
        }

        public enum DamageType : int
        {
            NormalPhysical = 0,
            NormalMagical = 1,
            NormalPhysicalSkill = 2,
            Additional = 3,
            NormalPhysicalLeftHand = 4,
            AdditionalLeftHand = 5,
            AdditionalMagical = 6,
            StateMagical = 7,
            StatePhysical = 8,
        }

        public enum DamageFlag : int
        {
            IgnoreAvoid = 2,
            IgnoreDefence = 4,
            IgnoreBlock = 8,
            IgnoreCritical = 16,
        }


//         public static Creature get(uint handle)
//         {
//             int v2; // esi@1
//             GameObject::iterator this; // [sp+8h] [bp-14h]@1
//             char buf[8]; // [sp+10h] [bp-Ch]@1
//             unsigned int v6; // [sp+18h] [bp-4h]@1
//             int v7; // [sp+1Ch] [bp+0h]@1
// 
//             *(_DWORD *)&buf[4] = 0;
//             *(_DWORD *)buf = &StructCreature::iterator::_vftable_;
//             *(_DWORD *)&buf[4] = GameObject.get(&this, handle)->m_pObject;
//             v2 = *(_DWORD *)&buf[4];
//             GameObject::iterator::_iterator(&this);
//             if ( v2 && !(unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v2 + 20))(v2) )
//                 *(_DWORD *)&buf[4] = 0;
//             StructCreature::iterator::iterator(result, (StructCreature::iterator *)buf);
//             return result;
// 
//         }

        public static void SetMaxSkillUID(int nUID)
        {
            s_nMaxSkillUID = nUID;
        }

        public static void InitCreatureSystem()
        {
            if (GameContent.g_pQuadScanner == null)
            {
                GameContent.g_pQuadScanner = new QuadTreeScanner(GameContent.g_nMapHeight, GameContent.g_nMapWidth);
            }
        }

        public static void DeInitCreatureSystem()
        {

        }
        public QuadTreeItem quadTreeItem = new QuadTreeItem();                               // 0xB8
        public static CreatureStat baseStat = new CreatureStat();
 
// Function       :   public void StructCreature(const struct StructCreature &)
        public Creature()
        {
            this.m_nTotalJobPoint = 0;
            this.m_nHP = 1;
            this.m_nMaxHP = 1;
            this.m_fMP = 1;
            this.m_nMaxMP = 1;
            this.m_StatusFlag |= StatusFlags.FirstEnter;
            this.quadTreeItem.Set(this);
            uint current_time = Globals.GetArTime();
            this.m_nDeadTime = current_time;
            this.m_nCastKeep = 100.0f;
            this.m_nMovableTime = 0;
            this.m_fBattleLevel = 1.0f;
            this.m_nNextAttackMode = 1;
            this.m_fItemMod = 1.0f;
            this.m_nHavoc = 0;
            this.m_fHealRatio = 1.0f;
            this.m_nMaxHavoc = 0;
            this.m_fMPHealRatio = 1.0f;
            this.m_nCriticalCount = 0;
            this.m_fHealRatioByItem = 1.0f;
            this.m_nMaxReachedLevel = 1;
            this.m_fMPHealRatioByItem = 1.0f;
            this.m_nLevel = 1;
            this.m_nEXP = 0;
            this.m_fHealRatioByRest = 2.0f;
            this.m_fMPHealRatioByRest = 2.0f;
            this.m_nLastDecreasedEXP = 0;
            this.m_nJob = 100;
            this.m_nJobLevel = 0;
            this.m_fHateRatio = 1.0f;
            this.m_nJobPoint = 0;
            this.m_nAdditionalHeal = 0;
            this.m_fResistHarmfulState = 0.0f;
            this.m_nAdditionalMPHeal = 0;
            this.m_nAdditionalHealByItem = 0;
            this.m_nAdditionalMPHealByItem = 0;
            this.m_nAdditionalHealByRest = 0;
            this.m_nAdditionalMPHealByRest = 0;
            this.m_nCurrentStateUID = 0;
            this.m_nPendedClearStateFlag = 0;
            this.m_nLastHavocUpdateTime = current_time;
            this.m_nLastUpdateTime = current_time;
            this.m_nLastStateProcTime = current_time;
            this.m_hEnemy = 0;
            this.m_StatusFlag |= StatusFlags.FirsAttack;
            this.m_hSkillTarget = 0;
            this.m_hTrap = 0;
            this.m_pCastSkill = null;
            this.m_fDetectHideRange = 0.0f;
            this.m_nPendingMoveSpeed = 0;
            this.m_StatusFlag |= (StatusFlags.NeedToCalculateStat | StatusFlags.Attackable | StatusFlags.SkillCastable | StatusFlags.Movable | StatusFlags.MagicCastable | StatusFlags.ItemUsable | StatusFlags.Mortal);
            this.m_nDoubleWeaponMasteryLevel = 0;

            for (int i = 0; i < 7; ++i)
            {
                m_GoodPhysicalElementalSkillStateMod[i] = new ElementalSkillStateMod();
                m_BadPhysicalElementalSkillStateMod[i] = new ElementalSkillStateMod();
                m_GoodMagicalElementalSkillStateMod[i] = new ElementalSkillStateMod();
                m_BadMagicalElementalSkillStateMod[i] = new ElementalSkillStateMod();
            }
            for (int i = 0; i < 10; ++i)
            {
                m_Expert[i] = new ExpertMod();
            }



        }

        public override bool IsCreature()
        {
            return true;
        }

        public virtual string GetName()
        {
            return "UnknownCreature";
        }

        public virtual int GetSID()
        {
            return 0;
        }
// Function       :   public int StructCreature::GetStatId()
        public int GetLevel()
        {
            return this.m_nLevel;
        }

        public void SetLevel(int lvl)
        {
            this.m_nLevel = lvl;
        }

        public int GetMaxReachedLevel()
        {
            return this.m_nMaxReachedLevel;
        }

        public void SetMaxReachedLevel(int nMaxReachedLevel)
        {
            this.m_nMaxReachedLevel = nMaxReachedLevel;
        }

        public virtual float GetBattleLevel()
        {
            return m_fBattleLevel;
        }

        public int GetJobId()
        {
            return this.m_nJob;
        }

        public int GetJobLevel()
        {
            return this.m_nJobLevel;
        }

        public int GetPrevJobLevel(int nDepth)
        {
            int result;

            if ((uint)nDepth > 2)
                result = 0;
            else
                result = this.m_nPrevJobLevel[nDepth];
            return result;
        }
        
        public int GetPrevJobId(int nDepth)
        {
            int result;

            if ((uint)nDepth > 3 )
                result = 0;
            else
                result = m_nPrevJobId[nDepth];
            return result;
        }

        public int GetJobDepth()
        {
            JobInfo info;
            int result;

            info = GameContent.GetJobInfo(GetJobId());
            if (info != null)
                result = info.job_depth;
            else
                result = 0;
            return result;
        }

        public void SetJobLevel(int jlvl)
        {
            this.m_nJobLevel = jlvl;
            this.onJobLevelUp();
        }

        public void SetPrevJobLevel(int nDepth, int jl)
        {
            if ((uint)nDepth <= 2)
                this.m_nPrevJobLevel[nDepth] = jl;
        }

        public void SetPrevJobId(int nDepth, int jid)
        {
              if ((uint)nDepth <= 2)
                this.m_nPrevJobId[nDepth] = jid;
        }

        public long GetJobPoint()
        {
            return m_nJobPoint;
        }


        public long GetTotalJobPoint()
        {
            return m_nTotalJobPoint;
        }


        public virtual void AddExp(long exp, long jp, bool bApplyStamina)
        {
            this.m_nEXP += exp;
            this.m_nJobPoint += jp;
            if ( jp > 0 )
                this.m_nTotalJobPoint += jp;
            if ((this.m_StatusFlag & StatusFlags.LoginComplete) != 0)
                this.onExpChange();
        }

// Function       :   public __int64 GetEXP()
// Function       :   public __int64 GetLastDecreasedEXP()
// Function       :   public void SetLastDecreasedEXP(__int64)
        
        public void SetEXP(long exp)
        {
            this.m_nEXP = exp;
            if (this.IsLoginComplete())
                this.onExpChange();
        }

        public void SetJP(long jp)
        {
            this.m_nJobPoint = jp;
            if (jp < 0)
                this.m_nJobPoint = 0;
            if (this.IsLoginComplete())
                this.onExpChange();
        }

        public virtual uint GetSkinColor()
        {
            return 0;
        }

// Function       :   public bool StructCreature::IsBackOf(const struct StructCreature &)
// Function       :   public bool StructCreature::IsSideOf(const struct StructCreature &)
// Function       :   public int GetHP()
// Function       :   public int GetMaxHP()

        public byte GetHPPercentage()
        {
            byte r = (byte) ((float)this.m_nHP / (float)this.m_nMaxHP * 100.0f);
            if (this.m_nHP != 0)
            {
                if (r == 0)
                    r = 1;
            }
            else
            {
                r = 0;
            }
            return r;

        }
// Function       :   public int GetMP()
        // Function       :   public int GetMaxMP()

        public byte GetMPPercentage()
        {
            byte r = (byte)((float)this.m_fMP / (float)this.m_nMaxMP * 100.0f);
            if (this.m_fMP != 0)
            {
                if (r == 0)
                    r = 1;
            }
            else
            {
                r = 0;
            }
            return r;
        }

        public int AddHP(int hp)
        {
            return this.SetHP(hp + this.m_nHP);
        }

        public int Heal(int hp)
        {
            int result;
            if (this.IsMagicalImmune())
            {
                result = 0;
            }
            else
            {
                result = (int)((this.m_fHealRatio * (float)hp) + this.m_nAdditionalHeal);
                this.AddHP(result);
            }
            return result;

        }

        public int HealByItem(int hp)
        {
            int result;

            if (this.IsMagicalImmune())
            {
                result = 0;
            }
            else
            {
                result = (int)((this.m_fHealRatioByItem * (float)hp) + this.m_nAdditionalHealByItem);
                this.AddHP(result);
            }
            return result;
        }

        public float AddMP(float mp)
        {
            return this.SetMP(mp + this.m_fMP);
        }

        public float MPHeal(float mp)
        {
            float result;

            if (this.IsMagicalImmune())
            {
                result = 0;
            }
            else
            {
                result = (this.m_fMPHealRatio * mp + this.m_nAdditionalMPHeal);
                this.AddMP(result);
            }
            return result;
        }

        public float MPHealByItem(float mp)
        {
            float result;

            if (this.IsMagicalImmune())
            {
                result = 0;
            }
            else
            {
                result = (this.m_fMPHealRatioByItem * mp + this.m_nAdditionalMPHealByItem);
                this.AddMP(result);
            }
            return result;
        }

        public void RegenFullHPMP()
        {

        }
// Function       :   public float GetHateRatio()
        public int SetHP(int hp)
        {
            int old_hp = m_nHP;
            m_nHP = hp;
            if (hp > m_nMaxHP)
                m_nHP = m_nMaxHP;
            if (m_nHP < 0)
                m_nHP = 0;
            if (old_hp != m_nHP)
                this.onHPChange(old_hp);
            return m_nHP;
        }
        public float SetMP(float mp)
        {
            float old_mp = this.m_fMP;
            this.m_fMP = mp;
            if (mp > m_nMaxMP)
                this.m_fMP = m_nMaxMP;
            if (this.m_fMP < 0)
                this.m_fMP = 0;
            return m_fMP;
        }
// Function       :   public int GetEnergyCount()
// Function       :   public int GetMaxEnergyCount()
// Function       :   public void StructCreature::AddEnergy()

        public void RemoveEnergy(int nEnergy)
        {
            int energy = this.m_nEnergy - nEnergy;
            if (this.m_nEnergy - nEnergy < 0)
                energy = nEnergy;

            if (energy >= 1 )
            {
                this.m_nEnergy -= energy;
                this.m_nEnergyStartPos += energy;

                if (this.m_nEnergyStartPos >= 10 )
                    this.m_nEnergyStartPos -= 10;
                this.onEnergyChange();
            }
        }

// Function       :   public int GetCastKeep()
        public void CalculateStat()
        {
            CreatureAttributeServer stateAttr;
            CreatureStat stateStat;
            int prev_max_mp; 
            int prev_max_hp;
            int prev_hp;
            float prev_mp;

            prev_hp = this.m_nHP;
            prev_max_hp = this.m_nMaxHP;
            prev_mp = this.m_fMP;
            prev_max_mp = this.m_nMaxMP;

            this.m_fHPRegenMod = 1.0f;
            this.m_fMPRegenMod = 1.0f;
            this.m_fMaxHPAmplifier = 0.0f;
            this.m_fMaxMPAmplifier = 0.0f;
            this.m_fHealRatio = 1.0f;
            this.m_fMPHealRatio = 1.0f;
            this.m_fHealRatioByItem = 1.0f;
            this.m_fMPHealRatioByItem = 1.0f;
            this.m_fHealRatioByRest = 2.0f;
            this.m_fMPHealRatioByRest = 2.0f;
            this.m_nMaxHP = 0;
            this.m_nMaxMP = 0;
            this.m_nMaxHavoc = 0;
            this.m_fHateRatio = 1.0f;
            this.m_nAdditionalHeal = 0;
            this.m_nAdditionalMPHeal = 0;
            this.m_fResistHarmfulState = 0.0f;
            this.m_nAdditionalHealByItem = 0;
            this.m_nAdditionalMPHealByItem = 0;
            this.m_nCastKeep = 100.0f;
            this.m_nAdditionalHealByRest = 0;
            this.m_nAdditionalMPHealByRest = 0;
            this.m_fBattleLevel = (float)m_nLevel;
            this.m_fBowInterval = 0.0f;
            this.m_fCreatureCardChance = 1.0f;
            this.m_nEnergyUpkeepTime = 180000;
            this.m_fPhysicalDamageManaShieldAbsorbRatio = 0.0f;
            this.m_nAttackPointRightWithoutWeapon = 0;
            this.m_fMagicalDamageManaShieldAbsorbRatio = 0.0f;
            this.m_nAttackPointLeftWithoutWeapon = 0;
            this.m_nMaxEnergy = this.IsSummon() ? 5 : 0;

            this.m_vStateByNormalAttack.Clear();
            this.m_vAmplifyPassiveSkillList.Clear();
            this.m_vAbsorbByNormalAttack.Clear();
            this.m_vHealOnAttack.Clear();
            this.m_vInterruptedSkill.Clear();
            this.m_vAddHPMPOnCritical.Clear();
            this.m_vDamageReducePercentInfo.Clear();
            this.m_vDamageReduceValueInfo.Clear();
            this.m_NormalStateAdvantage.fDamage = 1.0f;
            this.m_NormalStateAdvantage.fCritical = 1.0f;
            this.m_NormalStateAdvantage.nDamage = 0;
            this.m_NormalStateAdvantage.fHate = 1.0f;
            this.m_NormalStateAdvantage.nCritical = 0;
            this.m_RangeStateAdvantage.fDamage = 1.0f;
            this.m_RangeStateAdvantage.nDamage = 0;
            this.m_RangeStateAdvantage.fCritical = 1.0f;
            this.m_RangeStateAdvantage.nCritical = 0;
            this.m_RangeStateAdvantage.fHate = 1.0f;
            this.m_NormalStatePenalty.fDamage = 1.0f;
            this.m_NormalStatePenalty.nDamage = 0;
            this.m_NormalStatePenalty.fCritical = 1.0f;
            this.m_NormalStatePenalty.nCritical = 0;
            this.m_NormalStatePenalty.fHate = 1.0f;
            this.m_RangeStatePenalty.fDamage = 1.0f;
            this.m_RangeStatePenalty.nDamage = 0;
            this.m_RangeStatePenalty.fCritical = 1.0f;
            this.m_RangeStatePenalty.nCritical = 0;
            this.m_RangeStatePenalty.fHate = 1.0f;
            this.m_PhysicalSkillStatePenalty.fDamage = 1.0f;
            this.m_PhysicalSkillStatePenalty.nDamage = 0;
            this.m_PhysicalSkillStatePenalty.fCritical = 1.0f;
            this.m_PhysicalSkillStatePenalty.nCritical = 0;
            this.m_PhysicalSkillStatePenalty.fHate = 1.0f;
            this.m_MagicalSkillStatePenalty.fDamage = 1.0f;
            this.m_MagicalSkillStatePenalty.nDamage = 0;
            this.m_MagicalSkillStatePenalty.fCritical = 1.0f;
            this.m_MagicalSkillStatePenalty.nCritical = 0;
            this.m_MagicalSkillStatePenalty.fHate = 1.0f;
            this.m_StateStatePenalty.fDamage = 1.0f;
            this.m_StateStatePenalty.nDamage = 0;
            this.m_StateStatePenalty.fCritical = 1.0f;
            this.m_StateStatePenalty.nCritical = 0;
            this.m_StateStatePenalty.fHate = 1.0f;

            for(int i = 0; i < 7; ++i)
            {
                this.m_GoodPhysicalElementalSkillStateMod[i].Init();
                this.m_BadPhysicalElementalSkillStateMod[i].Init();
                this.m_GoodMagicalElementalSkillStateMod[i].Init();
                this.m_BadMagicalElementalSkillStateMod[i].Init();
            }

            this.m_nElementalEffectAttackPointRight = 0;
            this.m_nElementalEffectAttackPointLeft = 0;
            this.m_nElementalEffectMagicPoint = 0;
            this.m_StatusFlag |= (StatusFlags.Attackable | StatusFlags.SkillCastable | StatusFlags.Movable | StatusFlags.MagicCastable | StatusFlags.ItemUsable | StatusFlags.Mortal);
            this.m_StatusFlag &= ~(StatusFlags.Hiding | StatusFlags.HavocBurst | StatusFlags.Feared | StatusFlags.FormChanged | StatusFlags.MoveSpeedFixed);
            this.m_fDetectHideRange = 0.0f;
            this.m_StatusFlag &= ~(StatusFlags.HPRegenStopped | StatusFlags.MPRegenStopped);
            this.m_nDoubleWeaponMasteryLevel = 0;
            stateStat = new CreatureStat();
            stateAttr = new CreatureAttributeServer();

            this.m_StatByState.Reset(0);
            this.m_StatAmplifier.Reset(0.0f);
            this.m_AttributeByState.Reset(0);
            this.m_AttributeAmplifier.Reset(0);
            this.m_Attribute.Reset(0);
            this.m_Resist.Reset(0);
            this.m_ResistAmplifier.Reset(0.0f);
            for (int i = 0; i < 10; ++i)
            {
                this.m_Expert[i].Reset(0);
            }
            this.m_vNormalAdditionalDamage.Clear();
            this.m_vRangeAdditionalDamage.Clear();
            this.m_vPhysicalSkillAdditionalDamage.Clear();
            this.m_vMagicalSkillAdditionalDamage.Clear();
            this.m_vDamageReflectInfo.Clear();
            this.m_vStateReflectInfo.Clear();
            this.m_vHateMod.Clear();
            this.m_vStealOnAttack.Clear();
            this.m_vSetItemEffect.Clear();

            CreatureStat baseStat = this.GetBaseStat();
            this.m_Stat.Copy(baseStat);
            this.onBeforeCalculateStat();
            this.checkAdditionalItemEffect();
            this.applyStatByItem();
            this.applyJobLevelBonus();
            stateStat.Copy(m_Stat);
            this.applyStatByState();
            m_StatByState.strength += (m_Stat.strength - stateStat.strength);
            m_StatByState.vital += (m_Stat.vital - stateStat.vital);
            m_StatByState.dexterity += (m_Stat.dexterity - stateStat.dexterity);
            m_StatByState.agility += (m_Stat.agility - stateStat.agility);
            m_StatByState.intelligence += (m_Stat.intelligence - stateStat.intelligence);
            m_StatByState.mentality += (m_Stat.mentality - stateStat.mentality);
            m_StatByState.luck += (m_Stat.luck - stateStat.luck);
            this.onApplyStat();
            this.amplifyStatByItem();
            stateStat.Copy(m_Stat);
            this.getAmplifiedStatByAmplifier(stateStat);
            this.amplifyStatByState();
            this.getAmplifiedStatByAmplifier(m_Stat);
            m_StatByState.strength += (m_Stat.strength - stateStat.strength);
            m_StatByState.vital += (m_Stat.vital - stateStat.vital);
            m_StatByState.dexterity += (m_Stat.dexterity - stateStat.dexterity);
            m_StatByState.agility += (m_Stat.agility - stateStat.agility);
            m_StatByState.intelligence += (m_Stat.intelligence - stateStat.intelligence);
            m_StatByState.mentality += (m_Stat.mentality - stateStat.mentality);
            m_StatByState.luck += (m_Stat.luck - stateStat.luck);
            this.onAfterApplyStat();
            this.finalizeStat();
            float bl = this.GetBattleLevel();
            float fcm = GetFCM();
            // 33*Vit + 20*Lv + Equip + Skill + Buff 
            m_nMaxHP += (int)((m_Stat.vital * 33.0f) + (bl * 20.0f));
            fcm = GetFCM();
            bl = GetBattleLevel();
            m_nMaxMP += GameRule.GetMaxMP(m_Stat.intelligence, (int)bl, fcm);
            this.calcAttribute(m_Attribute);
            this.onAfterCalculateAttributeByStat();
            this.applyItemEffect();
            this.applyPassiveSkillEffect();
            stateAttr.Copy(m_Attribute);
            this.applyStateEffect();
            m_AttributeByState.nCritical += (m_Attribute.nCritical - stateAttr.nCritical);
            m_AttributeByState.nAttackPointRight += (m_Attribute.nAttackPointRight - stateAttr.nAttackPointRight);
            m_AttributeByState.nAttackPointLeft += (m_Attribute.nAttackPointLeft - stateAttr.nAttackPointLeft);
            m_AttributeByState.nDefence += (m_Attribute.nDefence - stateAttr.nDefence);
            m_AttributeByState.nBlockDefence += (m_Attribute.nBlockDefence - stateAttr.nBlockDefence);
            m_AttributeByState.nMagicPoint += (m_Attribute.nMagicPoint - stateAttr.nMagicPoint);
            m_AttributeByState.nMagicDefence += (m_Attribute.nMagicDefence - stateAttr.nMagicDefence);
            m_AttributeByState.nAccuracyRight += (m_Attribute.nAccuracyRight - stateAttr.nAccuracyRight);
            m_AttributeByState.nAccuracyLeft += (m_Attribute.nAccuracyLeft- stateAttr.nAccuracyLeft);
            m_AttributeByState.nMagicAccuracy += (m_Attribute.nMagicAccuracy - stateAttr.nMagicAccuracy);
            m_AttributeByState.nAvoid += (m_Attribute.nAvoid - stateAttr.nAvoid);
            m_AttributeByState.nMagicAvoid += (m_Attribute.nMagicAvoid - stateAttr.nMagicAvoid);
            m_AttributeByState.nBlockChance += (m_Attribute.nBlockChance - stateAttr.nBlockChance);
            m_AttributeByState.nMoveSpeed += (m_Attribute.nMoveSpeed - stateAttr.nMoveSpeed);
            m_AttributeByState.nAttackSpeedRight += (m_Attribute.nAttackSpeedRight - stateAttr.nAttackSpeedRight);
            m_AttributeByState.nAttackSpeedLeft += (m_Attribute.nAttackSpeedLeft - stateAttr.nAttackSpeedLeft);
            m_AttributeByState.nDoubleAttackRatio += (m_Attribute.nDoubleAttackRatio - stateAttr.nDoubleAttackRatio);
            m_AttributeByState.nAttackRange += (m_Attribute.nAttackRange - stateAttr.nAttackRange);
            m_AttributeByState.nMaxWeight += (m_Attribute.nMaxWeight - stateAttr.nMaxWeight);
            m_AttributeByState.nCastingSpeed += (m_Attribute.nCastingSpeed - stateAttr.nCastingSpeed);
            m_AttributeByState.nCoolTimeSpeed += (m_Attribute.nCoolTimeSpeed - stateAttr.nCoolTimeSpeed);
            m_AttributeByState.nHPRegenPercentage += (m_Attribute.nHPRegenPercentage - stateAttr.nHPRegenPercentage);
            m_AttributeByState.nHPRegenPoint += (m_Attribute.nHPRegenPoint - stateAttr.nHPRegenPoint);
            m_AttributeByState.nMPRegenPercentage += (m_Attribute.nMPRegenPercentage - stateAttr.nMPRegenPercentage);
            m_AttributeByState.nMPRegenPoint += (m_Attribute.nMPRegenPoint - stateAttr.nMPRegenPoint);
            this.applyPassiveSkillAmplifyEffect();
            this.onApplyAttributeAdjustment();
            stateAttr.Copy(m_Attribute);
            this.getAmplifiedAttributeByAmplifier(stateAttr);
            this.applyStateAmplifyEffect();
            this.getAmplifiedAttributeByAmplifier(m_Attribute);
            m_nAttackPointRightWithoutWeapon = (short)(m_AttributeAmplifier.fAttackPointRight * (float)m_nAttackPointRightWithoutWeapon);
            m_nAttackPointLeftWithoutWeapon = (short)(m_AttributeAmplifier.fAttackPointLeft * (float)m_nAttackPointLeftWithoutWeapon);
            m_AttributeByState.nCritical += (m_Attribute.nCritical - stateAttr.nCritical);
            m_AttributeByState.nAttackPointRight += (m_Attribute.nAttackPointRight - stateAttr.nAttackPointRight);
            m_AttributeByState.nAttackPointLeft += (m_Attribute.nAttackPointLeft - stateAttr.nAttackPointLeft);
            m_AttributeByState.nDefence += (m_Attribute.nDefence - stateAttr.nDefence);
            m_AttributeByState.nBlockDefence += (m_Attribute.nBlockDefence - stateAttr.nBlockDefence);
            m_AttributeByState.nMagicPoint += (m_Attribute.nMagicPoint - stateAttr.nMagicPoint);
            m_AttributeByState.nMagicDefence += (m_Attribute.nMagicDefence - stateAttr.nMagicDefence);
            m_AttributeByState.nAccuracyRight += (m_Attribute.nAccuracyRight - stateAttr.nAccuracyRight);
            m_AttributeByState.nAccuracyLeft += (m_Attribute.nAccuracyLeft - stateAttr.nAccuracyLeft);
            m_AttributeByState.nMagicAccuracy += (m_Attribute.nMagicAccuracy - stateAttr.nMagicAccuracy);
            m_AttributeByState.nAvoid += (m_Attribute.nAvoid - stateAttr.nAvoid);
            m_AttributeByState.nMagicAvoid += (m_Attribute.nMagicAvoid - stateAttr.nMagicAvoid);
            m_AttributeByState.nBlockChance += (m_Attribute.nBlockChance - stateAttr.nBlockChance);
            m_AttributeByState.nMoveSpeed += (m_Attribute.nMoveSpeed - stateAttr.nMoveSpeed);
            m_AttributeByState.nAttackSpeedRight += (m_Attribute.nAttackSpeedRight - stateAttr.nAttackSpeedRight);
            m_AttributeByState.nAttackSpeedLeft += (m_Attribute.nAttackSpeedLeft - stateAttr.nAttackSpeedLeft);
            m_AttributeByState.nDoubleAttackRatio += (m_Attribute.nDoubleAttackRatio - stateAttr.nDoubleAttackRatio);
            m_AttributeByState.nAttackRange += (m_Attribute.nAttackRange - stateAttr.nAttackRange);
            m_AttributeByState.nMaxWeight += (m_Attribute.nMaxWeight - stateAttr.nMaxWeight);
            m_AttributeByState.nCastingSpeed += (m_Attribute.nCastingSpeed - stateAttr.nCastingSpeed);
            m_AttributeByState.nCoolTimeSpeed += (m_Attribute.nCoolTimeSpeed - stateAttr.nCoolTimeSpeed);
            m_AttributeByState.nHPRegenPercentage += (m_Attribute.nHPRegenPercentage - stateAttr.nHPRegenPercentage);
            m_AttributeByState.nHPRegenPoint += (m_Attribute.nHPRegenPoint - stateAttr.nHPRegenPoint);
            m_AttributeByState.nMPRegenPercentage += (m_Attribute.nMPRegenPercentage - stateAttr.nMPRegenPercentage);
            m_AttributeByState.nMPRegenPoint += (m_Attribute.nMPRegenPoint - stateAttr.nMPRegenPoint);
            m_Attribute.nAttackPointRight += (m_nElementalEffectAttackPointRight);
            m_Attribute.nAttackPointLeft += (m_nElementalEffectAttackPointLeft);
            m_Attribute.nMagicPoint += (m_nElementalEffectMagicPoint);
            this.applyDoubleWeaponEffect();
            m_nMaxHP = (int)((m_fMaxHPAmplifier + 1.0f) * (float)m_nMaxHP);
            m_nMaxMP = (int)((m_fMaxMPAmplifier + 1.0f) * (float)m_nMaxMP);
            this.getAmplifiedResistByAmplifier(m_Resist);
            this.onCompleteCalculateStat();
            m_Attribute.nAttackSpeed = m_Attribute.nAttackSpeedRight;
            if ( m_Attribute.nAttackSpeed < 10 )
                m_Attribute.nAttackSpeed = 10;
            if ( m_Attribute.nMoveSpeed < 10 && !this.IsMonster())
                m_Attribute.nMoveSpeed = 10;
            if (m_Attribute.nCritical > 100)
                m_Attribute.nCritical = 100;
            this.SetHP(m_nHP);
            this.SetMP(m_fMP);
            this.onModifyStatAndAttribute();
            if (bIsInWorld && (prev_max_hp != m_nMaxHP || prev_max_mp != m_nMaxMP || prev_hp != m_nHP || prev_mp != m_fMP))
            {
                Messages.BroadcastHPMPMsg(this, m_nHP - prev_hp, this.m_fMP - prev_mp, false);
            }
            else
            {
                if (this.IsSummon() && !bIsInWorld && (prev_max_hp != m_nMaxHP || prev_max_mp != m_nMaxMP || prev_hp != m_nHP || prev_mp != m_fMP))
                {
                    Summon s = (Summon)this;
                    if (s != null)
                        Messages.SendHPMPMsg(s.m_master, this, m_nHP - prev_hp, m_fMP - prev_mp, false);
                }
            }

        }

        public virtual bool IsUsingBow()
        {
            return false;
        }

        public virtual bool IsUsingCrossBow()
        {
            return false;
        }

        public virtual bool IsUsingDoubleWeapon()
        {
            return (this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0;
        }

        public virtual long GetBulletCount()
        {
            long result;

            Item item = this.GetWornItem(ItemBase.ItemWearType.WearShield);
            if (item != null && item.m_pItemBase.nGroup == 98)
            {
                result = item.m_Instance.nCount;
            }
            else
            {
                result = 0;
            }
            return result;
        }

        public bool IsWearShield()
        {
            bool result;

            Item item = this.GetWornItem(ItemBase.ItemWearType.WearShield);
            if (item != null)
                result = item.m_pItemBase.nClass == ItemBase.ItemClass.ClassShield;
            else
                result = false;
            return result;
        }
// Function       :   public bool IsWearArmor()

        public virtual bool TranslateWearPosition(ref ItemBase.ItemWearType pos, Item item, ref List<int> ItemList)
        {
            bool result;
            if (item.GetWearType() != ItemBase.ItemWearType.WearCantWear && item.IsWearable())
            {
                int elevel = m_nUnitExpertLevel;
                int level = this.GetLevel();
                if ( m_nUnitExpertLevel <= level)
                    elevel = level;
                result = (item.GetLevelLimit() <= elevel) && ((item.m_pItemBase.nMinLevel == 0 || level >= item.m_pItemBase.nMinLevel)
                      && (item.m_pItemBase.nMaxLevel == 0 || level <= item.m_pItemBase.nMaxLevel));
            }
            else
            {
                result = false;
            }
            return result;
        }

        public ItemBase.ItemWearType GetAbsoluteWearPos(ItemBase.ItemWearType pos)
        {
            ItemBase.ItemWearType result;

            result = pos;
            if (this.m_anWear[(int)pos] == null)
                result = ItemBase.ItemWearType.WearCantWear;
            return result;
        }
// Function       :   public bool IsWearable(enum ItemBase::ItemWearType, struct StructItem *)

        public bool IsWornByCode(int code)
        {
            foreach (Item i in this.m_anWear)
            {
                if(i.m_pItemBase.nCode == code)
                    return true;
            }
            return false;
        }
// Function       :   public bool IsWeared(unsigned int)
        public Item GetWornItem(ItemBase.ItemWearType idx)
        {
            if ((uint)idx >= (ItemBase.MAX_ITEM_WEAR))
                return null;
            else
                return m_anWear[(uint)idx];
        }
// Function       :   public struct StructItem * StructCreature::GetWearedItemByAbsolutePos(enum ItemBase::ItemWearType)

        public ushort Puton(ItemBase.ItemWearType pos, Item item)
        {
            if ( !item.IsInInventory() || item.m_Instance.nWearInfo != ItemBase.ItemWearType.WearCantWear)
                return 0;

            List<int> vOverlapItemList = new List<int>();

            if ( !this.TranslateWearPosition(ref pos, item, ref vOverlapItemList))
            {
                return 0;
            }

            foreach (int s in vOverlapItemList)
            {
                this.putoffItem((ItemBase.ItemWearType)s);
                if (this.m_anWear[s] != null)
                    return 0;
            }

            return this.putonItem(pos, item);
        }

        public ushort Putoff(ItemBase.ItemWearType pos)
        {
            int i;

            if (pos == ItemBase.ItemWearType.WearTwoHand)
                pos = ItemBase.ItemWearType.WearWeapon;
            if (pos == ItemBase.ItemWearType.WearTwoFingerRing)
                pos = ItemBase.ItemWearType.WearRing;
            if ((int) pos >= 24 || (int) pos < 0 )
                return 5;
            ItemBase.ItemWearType abspos = this.GetAbsoluteWearPos(pos);
            if (abspos == ItemBase.ItemWearType.WearCantWear)
                return 5;
            if ( pos != ItemBase.ItemWearType.WearBagSlot)
                return this.putoffItem(abspos);


            if (this.m_fWeight > this.m_Attribute.nMaxWeight)
                return 11;
            ItemBaseServer bs = this.m_anWear[(int)abspos].m_pItemBase;
            i = 0;

            while (bs.nOptType[i] != 20)
            {
                ++i;
                if ( i >= 4 )
                    return 5;
            }
            if ( i == -1 )
                return 5;

//            c_fixed<10000>::operator_<float>(bs.fOptVar1[i], &current_bag_capacity, this.m_fItemMod);
//            if (this.m_fWeight <= this.m_Attribute.nMaxWeight - current_bag_capacity.value / 10000.0 )
                return this.putoffItem(abspos);
        }
// Function       :   public void PutonSet(struct StructItem * *)
// Function       :   public bool SomethingInLeftHand()
// Function       :   public bool SomethingInRightHand()
// Function       :   public bool SomethingInHand()
// Function       :   public bool IsDead()
// Function       :   public bool IsAlive()

        public virtual bool IsSitDown()
        {
            return false;
        }
// Function       :   public unsigned long GetDeadTime()
// Function       :   public void SetDeadTime(unsigned long)
// Function       :   public bool IsFirstEnter()
// Function       :   public void SetFirstEnter(bool)

        public virtual byte GetRace()
        {
            return 0;
        }

        public virtual uint GetNextAttackableTime()
        {
            return this.m_nNextAttackableTime;
        }

        public virtual void SetNextAttackableTime(uint t)
        {
            this.m_nNextAttackableTime = t;
        }
// Function       :   public void SetMovableTime(unsigned long)
// Function       :   public unsigned long GetMovableTime()

        public bool SetPendingMove(List<ArPosition> newPos, byte speed)
        {
            if ((m_StatusFlag & StatusFlags.MovePending) != 0)
            {
                return false;
            }
            else
            {
                m_PendingMovePos = newPos;
                m_nPendingMoveSpeed = speed;
                m_StatusFlag |= StatusFlags.MovePending;
            }
            return true;
        }

        public void Attack(Creature pTarget, uint t, uint attack_interval, AttackInfo[] arDamage, ref bool bIsDoubleAttack)
        {
//            StructCreature::_DAMAGE_INFO result; // [sp+2Ch] [bp-84h]@17
            DamageInfo di;
            int i;
            int prev_target_hp;
            float prev_target_mp;
            int prev_hp;
            float prev_mp;
            int nAttackCount;
            int nHate;
            RappelzPair<float,int> HateMod;
            Player player;

            uint ct = t;
            if (ct == 0)
                ct = Globals.GetArTime();
            
            this.SetNextAttackableTime(attack_interval + ct);
            bIsDoubleAttack = false;
            
            nHate = 0;
            nAttackCount = 1;
            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                nAttackCount = 2;
            if (Globals.GetRandomInt32() % 100 < this.m_Attribute.nDoubleAttackRatio)
            {
                bIsDoubleAttack = true;
                nAttackCount *= 2;
            }
            i = 0;

            if (nAttackCount > 0)
            {
                //v11 = arDamage[i].mp_damage;
                do
                {
                    attack_interval = 0;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    {
                        if(((uint) i & 1) != 0)
                            attack_interval = 1;
                    }

                    prev_target_hp = pTarget.m_nHP;
                    prev_target_mp = pTarget.m_fMP;
                    prev_hp = this.m_nHP;
                    prev_mp = this.m_fMP;
                    int crit = 0;
                    if (this.m_nCriticalCount > 0)
                        crit = 50;

                    if (attack_interval != 0)
                        di = pTarget.DealPhysicalNormalLeftHandDamage(this, this.m_Attribute.nAttackPointLeft, Elemental.Type.TypeNone, 0, crit, 0);
                    else
                        di = pTarget.DealPhysicalNormalDamage(this, this.m_Attribute.nAttackPointRight, Elemental.Type.TypeNone,0,crit,0);
                    arDamage[i].SetDamageInfo(di);
                    if (arDamage[i].bCritical)
                    {
                        ++this.m_nCriticalCount;
                        if (this.m_nCriticalCount >= 3 )
                            this.m_nCriticalCount = 0;
                        this.ProcessAddHPMPOnCritical();
                    }

                    if (!arDamage[i].bMiss)
                    {

                        foreach (AddStateTag ast in this.m_vStateByNormalAttack)
                        {
                            if ((Globals.GetRandomInt32() % 100) < ast.percentage)
                            {
                                pTarget.AddState(State.StateType.Normal, ast.code, this.m_hHandle,ast.level, t, t + ast.duration, false, 0, "");
                            }
                        }

                        foreach (DamageAbsorbTag dat in this.m_vAbsorbByNormalAttack)
                        {
                            if ((Globals.GetRandomInt32() % 100) < dat.ratio)
                            {
                                if (dat.hp_absorb_ratio != 0.0f)
                                {
                                    this.AddHP((int)(dat.hp_absorb_ratio * arDamage[i].nDamage));
                                }
                                if (dat.mp_absorb_ratio != 0.0f)
                                {
                                    this.AddMP((int)(dat.mp_absorb_ratio * arDamage[i].nDamage));
                                }
                            }
                        }

                        foreach(HealOnAttackTag hoat in this.m_vHealOnAttack)
                        {
                            if ((Globals.GetRandomInt32() % 100) < hoat.ratio)
                            {
                                if (hoat.hp_inc != 0)
                                {
                                    this.AddHP(hoat.hp_inc);
                                }
                                if (hoat.mp_inc != 0)
                                {
                                    this.AddMP(hoat.mp_inc);
                                }
                            }
                        }

                        foreach(StealOnAttackTag soat in this.m_vStealOnAttack)
                        {
                            if ((Globals.GetRandomInt32() % 100) < soat.ratio)
                            {
                                if (soat.hp_steal != 0)
                                {
                                    int shp = soat.hp_steal;
                                    if (soat.hp_steal >= pTarget.m_nHP)
                                        shp = pTarget.m_nHP;

                                    this.AddHP(shp);
                                    pTarget.damage(this, shp, true);
                                }
                                if (soat.mp_steal != 0)
                                {
                                    float smp = soat.mp_steal;
                                    if (smp >= pTarget.m_fMP)
                                        smp = pTarget.m_fMP;
                                    this.AddMP(smp);
                                    pTarget.AddMP(-smp);
                                }
                            }
                        }

                        Item weapon = this.m_anWear[0];
                        if (attack_interval != 0)
                            weapon = this.m_anWear[1];

                        if (weapon != null && weapon.m_Instance.nCurrentEndurance > 0 && weapon.GetUsingSocketCount() > 0 )
                        {
                            int oldEndurance = weapon.m_Instance.nCurrentEndurance;
                            weapon.SetCurrentEndurance(oldEndurance - 500);
                            if (GameRule.GetDecreasedEndurancePoint(oldEndurance, weapon.m_Instance.nCurrentEndurance) > 0 )
                            {
                                player = null;
                                if (this.IsPlayer())
                                {
                                    player = this as Player;
                                }
                                else if (this.IsSummon())
                                {
                                    Summon summon = this as Summon;
                                    player = summon.m_master;
                                }
                                if (player != null)
                                {
                                    if (player.m_bIsLogin && player.bIsInWorld)
                                    {
                                        Messages.SendItemMessage(player, weapon);
                                    }
                                }
                            }

                            if (weapon.m_Instance.nCurrentEndurance == 0)
                                this.m_StatusFlag |= StatusFlags.FirsAttack;
                        }

                    }

                    arDamage[i].nDamage = prev_target_hp - pTarget.m_nHP;
                    arDamage[i].mp_damage = (short)(prev_target_mp - pTarget.m_fMP);
                    arDamage[i].attacker_damage = (short)(prev_hp - this.m_nHP);
                    arDamage[i].attacker_mp_damage = (short)(prev_mp - this.m_fMP);
                    arDamage[i].target_hp = pTarget.m_nHP;
                    arDamage[i].target_mp = (ushort)pTarget.m_fMP;
                    arDamage[i].attacker_hp = (uint)this.m_nHP;
                    arDamage[i].attacker_mp = (ushort)this.m_fMP;

                    nHate += arDamage[i].nDamage;
//                    this.onWrite(int,IConnection *);//(v29[9].IsDeleteable)(this, pTarget, arDamaga[i]);
                    if (!arDamage[i].bMiss)
                    {
                        this.SetHavoc(this.m_nHavoc - (int)((float)arDamage[i].nDamage * -0.009999999776482582f));
                        int nh;
                        if (arDamage[i].bPerfectBlock)
                        {
                            nh = pTarget.m_nHavoc + 200;
                        }
                        else
                        {
                            if (arDamage[i].bBlock)
                                nh = pTarget.m_nHavoc-(int)((float)arDamage[i].nDamage * -0.1000000014901161f);
                            else
                                nh = pTarget.m_nHavoc-(int)((float)arDamage[i].nDamage * -0.009999999776482582f);
                        }
                        pTarget.SetHavoc(nh);
                    }
                    ++i;
                }
                while ( i < nAttackCount );
            }
            if (pTarget.IsMonster())
            {
                Monster mob = pTarget as Monster;
                bool usingBow = this.IsUsingBow() || this.IsUsingCrossBow();
                if(!this.IsPlayer())
                    usingBow = false;

                HateMod = this.GetHateMod(3, true);
                nHate = (int)((float)(nHate + HateMod.Second) * HateMod.First);

                if (usingBow)
                    nHate = (int)((this.m_fHateRatio * (float)nHate) * this.m_RangeStateAdvantage.fHate * pTarget.m_RangeStatePenalty.fHate);
                else
                    nHate = (int)((this.m_fHateRatio * (float)nHate) * this.m_NormalStateAdvantage.fHate * pTarget.m_NormalStatePenalty.fHate);
                mob.AddHate(this.m_hHandle, nHate, true, true);
            }
            else
            {
                if (pTarget.IsNPC())
                {
                    NPC npc = pTarget as NPC;
                    npc.SetAttacker(pTarget);
                }
            }
        }

        public DamageInfo DealPhysicalNormalDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag)
        {
            DamageInfo result = new DamageInfo();
            StateMod damageReduceByState = new StateMod();
            int nTargetGroup;
            bool bRange;
            int damage;
// Data           :   ebp Relative, [FFFFFFC0], Local, Type: struct StructCreature::StateMod, damageReduceByState
// Data           :   ebp Relative, [FFFFFFD8], Local, Type: int, nTargetGroup
// Data           :   ebp Relative, [FFFFFFE8], Local, Type: class std::_Vector_iterator<StructCreature::DamageReduceInfo,std::allocator<StructCreature::DamageReduceInfo> >, dit
// Data           :   ebp Relative, [FFFFFFF3], Local, Type: bool, bRange
// Data           :   ebp Relative, [FFFFFFC4], Local, Type: class std::vector<StructCreature::AdditionalDamageInfo,std::allocator<StructCreature::AdditionalDamageInfo> >, AdditionalDamage
// Data           :   ebp Relative, [FFFFFFE8], Local, Type: class std::_Vector_iterator<StructCreature::AdditionalDamageInfo,std::allocator<StructCreature::AdditionalDamageInfo> >, it
// Data           :   ebp Relative, [FFFFFFD8], Local, Type: int, damage


//            damageReduceByState.Copy(this.m_NormalStatePenalty);
            
            nTargetGroup = pFrom.GetCreatureGroup();

//             iresult = *(v8 + 8);
//             from = *(v8 + 12);
//             This = this;
//             *(v8 - 44) = This;
//             *(v8 - 68) = from;

            if (pFrom.IsUsingBow() || pFrom.IsUsingCrossBow() && pFrom.IsPlayer())
            {
                bRange = true;
                damageReduceByState.Copy(this.m_RangeStatePenalty);
            }
            else
            {
                bRange = false;
                damageReduceByState.Copy(this.m_NormalStatePenalty);
            }

            foreach (DamageReduceInfo dri in this.m_vDamageReduceValueInfo)
            {
                if (dri.IsAppliableCreatureGroup(nTargetGroup))
                {
                    if(dri.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        damageReduceByState.nDamage -= (int)dri.physical_reduce;
                    }
                }
            }

            foreach (DamageReduceInfo dpi in this.m_vDamageReducePercentInfo)
            {
                if (dpi.IsAppliableCreatureGroup(nTargetGroup))
                {
                    if (dpi.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        damageReduceByState.fDamage -= dpi.physical_reduce;
                        if ( damageReduceByState.fDamage < 0.0f)
                            damageReduceByState.fDamage = 0.0f;
                    }
                }
            }

            if (nDamage < 0 )
                nDamage = 0;
            Damage d;
            if (bRange)
            {
                d = this.DealPhysicalDamage(pFrom, nDamage, elemental_type, accuracy_bonus, critical_bonus, nFlag, damageReduceByState, pFrom.m_RangeStateAdvantage);
            }
            else
            {
                d = this.DealPhysicalDamage(pFrom, nDamage, elemental_type, accuracy_bonus, critical_bonus, nFlag, damageReduceByState, pFrom.m_NormalStateAdvantage);
            }

            result.SetDamage(d);

            if (!result.bMiss && !result.bPerfectBlock )
            {
                List<AdditionalDamageInfo> v_add = pFrom.m_vRangeAdditionalDamage;
                if (!bRange)
                    v_add = pFrom.m_vNormalAdditionalDamage;

                foreach (AdditionalDamageInfo addi in v_add)
                {
                    if (addi.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        if (addi.nDamage != 0)
                            damage = addi.nDamage;
                        else
                            damage = (int)(addi.fDamage * (float)result.nDamage);

                        Damage dd = this.DealDamage(pFrom, damage, addi.type, DamageType.Additional, 0, 0, 0, null, null);
                        result.elemental_damage[(int)addi.type] += (ushort)dd.nDamage;
                        result.nDamage += dd.nDamage;
                    }
                }
            }
            result.target_hp = this.m_nHP;
            return result;
        }

        public DamageInfo DealPhysicalNormalLeftHandDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag)
        {
            int damage;
            DamageInfo result = new DamageInfo();
            StateMod damageReduceByState = new StateMod();

            damageReduceByState.Copy(this.m_NormalStatePenalty);
            
            int creatureGroup = pFrom.GetCreatureGroup();

            foreach (DamageReduceInfo dri in this.m_vDamageReduceValueInfo)
            {
                if (dri.IsAppliableCreatureGroup(creatureGroup))
                {
                    if(dri.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        damageReduceByState.nDamage -= (int)dri.physical_reduce;
                    }
                }
            }

            foreach (DamageReduceInfo dpi in this.m_vDamageReducePercentInfo)
            {
                if (dpi.IsAppliableCreatureGroup(creatureGroup))
                {
                    if (dpi.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        damageReduceByState.fDamage -= dpi.physical_reduce;
                        if ( damageReduceByState.fDamage < 0.0f)
                            damageReduceByState.fDamage = 0.0f;
                    }
                }
            }

            if (nDamage < 0)
                nDamage = 0;

            Damage d = this.DealPhysicalLeftHandDamage(pFrom, nDamage, elemental_type, accuracy_bonus, critical_bonus, nFlag, damageReduceByState, pFrom.m_NormalStateAdvantage);
            result.SetDamage(d);
            if (!result.bMiss && !result.bPerfectBlock) 
            {
                foreach (AdditionalDamageInfo adi in pFrom.m_vNormalAdditionalDamage)
                {
                    if (adi.ratio > (byte)(Globals.GetRandomInt32() % 100))
                    {
                        if (adi.nDamage != 0)
                            damage = adi.nDamage;
                        else
                            damage = (int)(adi.fDamage * (float)result.nDamage);

                        Damage dd = this.DealDamage(pFrom, damage, adi.type, DamageType.AdditionalLeftHand, 0, 0, 0, null, null);
                        result.elemental_damage[(int)adi.type] += (ushort)dd.nDamage;
                        result.nDamage += dd.nDamage;
                    }
                }
            }
            result.target_hp = this.m_nHP;
            return result;
        }


        public DamageInfo DealMagicalSkillDamage(Creature pFrom, int nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag)
        {
            StateMod damageReduceByState;                   // -88  -58h
            List<AdditionalDamageInfo> AdditionalDamage;    // -64  -40h
            int damage;                                     // -24  -18h
// .text:0042BB01 it              = std._Vector_iterator<StructCreature.AdditionalDamageInfo,std.allocator<StructCreature.AdditionalDamageInfo> > ptr -14h
            DamageInfo result = new DamageInfo();           // 4    4
// .text:0042BB01 pFrom           = dword ptr  0Ch
// .text:0042BB01 nDamage         = dword ptr  10h
// .text:0042BB01 elemental_type  = dword ptr  14h
// .text:0042BB01 accuracy_bonus  = dword ptr  18h
// .text:0042BB01 critical_bonus  = dword ptr  1Ch
// .text:0042BB01 nFlag           = dword ptr  20h
            int nTargetGroup;                               // -24  -18h


            nTargetGroup = pFrom.GetCreatureGroup();
            damageReduceByState = new StateMod(this.m_MagicalSkillStatePenalty);

//             public byte ratio;
//             public float physical_reduce;
//             public float physical_skill_reduce;
//             public float magical_skill_reduce;
//             public int[] apply_creature_group_list = new int[5];

//             public float fDamage;
//             public int nDamage;
//             public float fCritical;
//             public int nCritical;
//             public float fHate;


            foreach (DamageReduceInfo dri in this.m_vDamageReduceValueInfo)
            {
                if (dri.IsAppliableCreatureGroup(nTargetGroup))
                {
                    if (dri.ratio > Globals.GetRandomInt32() % 100)
                        damageReduceByState.nDamage -= (int)dri.magical_skill_reduce;
                }
            }

            foreach (DamageReduceInfo dri in this.m_vDamageReducePercentInfo)
            {
                if (dri.IsAppliableCreatureGroup(nTargetGroup))
                {
                    if (dri.ratio > Globals.GetRandomInt32() % 100)
                    {
                        damageReduceByState.fDamage -= dri.magical_skill_reduce;
                        if (damageReduceByState.fDamage < 0.0f)
                            damageReduceByState.fDamage = 0.0f;
                    }
                }
            }
            if (nDamage < 0 )
                nDamage = 0;

            Damage d = this.DealMagicalDamage(pFrom,(float)nDamage,elemental_type,
                      pFrom.m_BadMagicalElementalSkillStateMod[(int)elemental_type].nMagicalAccuracy + accuracy_bonus,
                      pFrom.m_BadMagicalElementalSkillStateMod[(int)elemental_type].nCritical + critical_bonus,
                      nFlag, damageReduceByState,null);
            result.SetDamage(d);
            if (!result.bMiss)
            {
                if (!result.bPerfectBlock)
                {
//             public byte ratio;
//             public Elemental.Type require_type;
//             public Elemental.Type type;
//             public ushort nDamage;
//             public float fDamage;

                    foreach (AdditionalDamageInfo adi in pFrom.m_vMagicalSkillAdditionalDamage)
                    {
                        if ((int)adi.require_type == 99 || adi.require_type == elemental_type)
                        {
                            if (adi.ratio > Globals.GetRandomInt32() % 100)
                            {
                                if (adi.nDamage != 0)
                                    damage = adi.nDamage;
                                else
                                    damage = (int)(adi.fDamage * (float)result.nDamage);
                                d = this.DealDamage(pFrom,damage,adi.type,DamageType.AdditionalMagical,0,0,0,null,null);

                                result.elemental_damage[(int)adi.type] += (ushort)d.nDamage;
                                result.nDamage += d.nDamage;
                            }
                        }
                    }
                }
            }
            result.target_hp = this.m_nHP;
            return result;
        }

// Function       :   public struct StructCreature::_DAMAGE_INFO StructCreature::DealPhysicalSkillDamage(struct StructCreature *, int, enum Elemental::Type, int, int, int)

        public Damage DealMagicalDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            return this.DealDamage(pFrom, nDamage, elemental_type, DamageType.NormalMagical,accuracy_bonus,critical_bonus,nFlag,damage_penalty,damage_advantage);
        }

        public Damage DealPhysicalDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            return this.DealDamage(pFrom, nDamage, elemental_type, DamageType.NormalPhysical, accuracy_bonus, critical_bonus, nFlag, damage_penalty, damage_advantage);
        }

        public Damage DealStateMagicalDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            return this.DealDamage(pFrom, nDamage, elemental_type, DamageType.StateMagical, accuracy_bonus, critical_bonus, nFlag, damage_penalty, damage_advantage);
        }

        public Damage DealPhysicalStateDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            return this.DealDamage(pFrom, nDamage, elemental_type, DamageType.StatePhysical, accuracy_bonus, critical_bonus, nFlag, damage_penalty, damage_advantage);
        }

        public Damage DealPhysicalLeftHandDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            return this.DealDamage(pFrom, nDamage, elemental_type, DamageType.NormalPhysicalLeftHand, accuracy_bonus, critical_bonus, nFlag, damage_penalty, damage_advantage);
        }

// Function       :   public struct StructCreature::_DAMAGE DealAdditionalDamage(struct StructCreature *, int, enum Elemental::Type, int, int, int, const struct StructCreature::StateMod *, const struct StructCreature::StateMod *)
// Function       :   public struct StructCreature::_DAMAGE DealAdditionalLeftHandDamage(struct StructCreature *, int, enum Elemental::Type, int, int, int, const struct StructCreature::StateMod *, const struct StructCreature::StateMod *)
// Function       :   public struct StructCreature::_DAMAGE DealAdditionalMagicalDamage(struct StructCreature *, int, enum Elemental::Type, int, int, int, const struct StructCreature::StateMod *, const struct StructCreature::StateMod *)

        public Damage DealDamage(Creature pFrom, float nDamage, Elemental.Type elemental_type, DamageType damageType, int accuracy_bonus, int critical_bonus, int nFlag, StateMod damage_penalty, StateMod damage_advantage)
        {
            Damage result = new Damage();

            uint t;//Data           :   ebp Relative, [00000028], Local, Type: unsigned long, t
            float mana_shield_absorb_ratio;//Data           :   ebp Relative, [00000028], Local, Type: float, 
            int real_damage;    //Data           :   ebp Relative, [00000020], Local, Type: int, 
            int nAbsorbableDamage;//Data           :   ebp Relative, [00000028], Local, Type: int, 
            State pFrozen;//// Data           :   ebp Relative, [00000028], Local, Type: struct StructState *, 
            int nRatio;// Data           :   ebp Relative, [00000028], Local, Type: int, 
            int pos;// Data           :   ebp Relative, [00000028], Local, Type: int, 
            ItemBase.ItemWearType[] WeaponIndices = new ItemBase.ItemWearType[6];// Data           :   ebp Relative, [FFFFFFA8], Local, Type: const enum ItemBase::ItemWearType[0x6], 
// Data           :   ebp Relative, [FFFFFFF8], Local, Type: class std::_Vector_iterator<StructCreature::StateReflectInfo,std::allocator<StructCreature::StateReflectInfo> >, it
// Data           :   ebp Relative, [FFFFFFF8], Local, Type: class std::_Vector_iterator<StructCreature::DamageReflectInfo,std::allocator<StructCreature::DamageReflectInfo> >, it
            int nReflectDamage;// Data           :   ebp Relative, [0000002C], Local, Type: int, 
            float nPrevMP;// Data           :   ebp Relative, [00000014], Local, Type: int, 
            float fDamageFlag;// Data           :   ebp Relative, [00000028], Local, Type: int, 
            int nDamageFlag;// Data           :   ebp Relative, [00000028], Local, Type: int, 
            int nPrevHP;// Data           :   ebp Relative, [00000008], Local, Type: int, 

            int nCritical;
            float fCritical;

            if (damage_penalty != null)
            {
                nCritical = damage_penalty.nCritical;
                fCritical = damage_penalty.fCritical - 1.0f;
            }
            else
            {
                nCritical = 0;
                fCritical = 0.0f;
            }

            if (damage_advantage != null)
            {
                nCritical += damage_advantage.nCritical;
                fCritical += damage_advantage.fCritical - 1.0f;
            }

            result = pFrom.CalcDamage(this, damageType, nDamage, elemental_type, accuracy_bonus, fCritical + 1.0f, critical_bonus + nCritical, nFlag);

            if (!result.bMiss)
            {
                if (damage_penalty != null)
                {
                    result.nDamage += damage_penalty.nDamage;
                    result.nDamage = (int)((float)result.nDamage * damage_penalty.fDamage);
                }
                if (damage_advantage != null)
                {
                    result.nDamage += damage_advantage.nDamage;
                    result.nDamage = (int)((float)result.nDamage * damage_advantage.fDamage);
                }
            }
            if (result.nDamage < 0)
                result.nDamage = 0;

//             if (damageType == DamageType.NormalPhysical)
//                 fDamageFlag = this.m_fPhysicalDamageManaShieldAbsorbRatio; // goto LABEL_26;
//             else if ( damageType == DamageType.NormalMagical)
//                 fDamageFlag = this.m_fMagicalDamageManaShieldAbsorbRatio; //goto LABEL_29;
// //             if ( damageType <= DamageType.NormalMagical)
// //                 goto LABEL_36;
//             else if ( damageType <= DamageType.AdditionalLeftHand)
//             {
//         LABEL_26:
//                 fDamageFlag = this.m_fPhysicalDamageManaShieldAbsorbRatio;
//                 goto LABEL_27;
//             }
//             if ( damageType > DamageType.StateMagical)
//             {
//                 if ( damageType != DamageType.StatePhysical)
//                     goto LABEL_36;
//                 fDamageFlag = this.m_fPhysicalDamageManaShieldAbsorbRatio;
//                 goto LABEL_27;
//             }
//         LABEL_29:
//             fDamageFlag = this.m_fMagicalDamageManaShieldAbsorbRatio;
//         LABEL_27:
//             fDamageFlag = v20;

            fDamageFlag = this.m_fPhysicalDamageManaShieldAbsorbRatio;

            if (fDamageFlag < 0.0f)
                fDamageFlag = 0.0f;
            if (fDamageFlag > 0.0f)
            {
                if(fDamageFlag > 1.0f)
                    fDamageFlag = 1.0f;
                nDamageFlag = (int)(result.nDamage * fDamageFlag);
                if (this.m_fMP < nDamageFlag)
                    nDamageFlag = (int)this.m_fMP;
                result.nDamage -= nDamageFlag;
                this.AddMP(-nDamageFlag);
                Messages.BroadcastHPMPMsg(this, 0, (short)nDamageFlag, false);
            }

            real_damage = this.onDamage(pFrom,elemental_type,damageType,result.nDamage,result.bCritical);
            this.damage(pFrom, real_damage, true);
            
//            if (this.m_pCastSkill != null)
//                this.m_pCastSkill.onDamage(result.nDamage);

            if (!result.bMiss)
            {
                this.RemoveStatesOnDamaged();
                this.RemoveState(State.StateCode.Sleep, 65535);
                this.RemoveState(State.StateCode.Nightmare, 65535);
                if ( damageType != DamageType.NormalMagical && damageType != DamageType.StateMagical)
                    this.RemoveState(State.StateCode.ShineWall, 65535);
                pFrozen = this.GetState(State.StateCode.Frozen);
                if (pFrozen != null)
                {
                    if (Globals.GetRandomInt32() % 100 < ((pFrozen.GetValue(4) + (pFrozen.GetLevel() * pFrozen.GetValue(5))) * 100))
                        this.RemoveState(State.StateCode.Frozen, 65535);
                }
/*
                nDamageFlagc = 0;
                do
                {
//                     WeaponIndices[0] = 2;
//                     WeaponIndices[1] = 3;
//                     WeaponIndices[2] = 4;
//                     WeaponIndices[3] = 5;
//                     WeaponIndices[4] = 6;
//                     WeaponIndices[5] = 7;
//                     v25 = WeaponIndices[nDamageFlagc];
                    Item wi = this.m_anWear[nDamageFlagc+2];
                    if (wi != null && wi.m_Instance.nCurrentEndurance > 0 && wi.GetUsingSocketCount() > 0 )
                    {
                        nReflectDamage = wi.m_Instance.nCurrentEndurance;
                        wi.SetCurrentEndurance(nReflectDamage - 75);
                        if (this.IsPlayer() && GameRule.GetDecreasedEndurancePoint(nReflectDamage, wi.m_Instance.nCurrentEndurance) > 0 )
                        {
                            Messages.SendItemMessage(this as Player, wi);
                        }
                        if (wi.m_Instance.nCurrentEndurance == 0)
                            this.m_StatusFlag |= StatusFlags.NeedToCalculateStat;
                    }
                    ++nDamageFlagc;
                }
                while ( nDamageFlagc < 6 );
                v19 = result;
*/
            }
            t = Globals.GetArTime();
/*
            if (result.bBlock)
            {
                if ( std::vector<StructCreature::AddHPMPOnCriticalInfo_std::allocator<StructCreature::AddHPMPOnCriticalInfo>>::size(&v11->m_vStateReflectInfo) )
                {
                    v27 = Globals.GetArTime();
                    v28 = ArObject::GetCurrentPosition(&v11->baseclass_0.baseclass_0, &v59, v27);
                    v29 = Globals.GetArTime();
                    v30 = ArObject::GetCurrentPosition(&pFrom->baseclass_0.baseclass_0, &v61, v29);
                    if ( ArPosition::GetDistance(v30, v28) <= 48.0 )
                    {
                        std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                            &it,
                            v11->m_vStateReflectInfo._Myfirst,
                            &v11->m_vStateReflectInfo.baseclass_0.___u0.baseclass_0);
                        v53 = &v11->m_vStateReflectInfo;
                        for ( i = v11->m_vStateReflectInfo._Mylast; ; i = v11->m_vStateReflectInfo._Mylast )
                        {
                            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                                &thisa,
                                i,
                                v53);
                            if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                                     &it,
                                     &thisa) )
                                break;
                            if ( !pFrom->baseclass_0.baseclass_0.baseclass_0.vfptr[1].IsDeleteable(pFrom) )
                            {
                                nReflectDamagee = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                nPrevMPa = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                nPrevHPa = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                v31 = nDamageFlagd + LODWORD(nReflectDamagee->end.z);
                                v32 = LODWORD(nPrevMPa->end.y);
                                v33 = v11->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v11);
                                StructCreature::AddState(pFrom, 0, *nPrevHPa, v33, v32, nDamageFlagd, v31, 0, 0, &unk_5F42BB);
                            }
                            std::_Vector_const_iterator<_DAMAGE_TAG_std::allocator<_DAMAGE_TAG>>::operator__(&it);
                            v53 = &v11->m_vStateReflectInfo;
                        }
                    }
                }
            }
*/
/*
            if ((this.m_StatusFlag & StatusFlags.ProcessingReflect) == 0 && (pFrom.m_StatusFlag & StatusFlags.ProcessingReflect) == 0 && this.m_vDamageReflectInfo.Count > 0)
            {
                this.m_StatusFlag |= StatusFlags.ProcessingReflect;
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &it,
                    v11->m_vDamageReflectInfo._Myfirst,
                    &v11->m_vDamageReflectInfo.baseclass_0.___u0.baseclass_0);
                v54 = &v11->m_vDamageReflectInfo;
                for ( j = v11->m_vDamageReflectInfo._Mylast; ; j = v11->m_vDamageReflectInfo._Mylast )
                {
                    std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                        &thisa,
                        j,
                        v54);
                    if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                             &it,
                             &thisa) )
                    {
                        this.m_StatusFlag &= ~StatusFlags.ProcessingReflect;
                        break;
                    }
                    nDamageFlagg = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                    if ( XRandom(0, 0x64u) >= LOBYTE(nDamageFlagg->end.x)
                      || (nDamageFlagh = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it),
                          v34 = Globals.GetArTime(),
                          v35 = this.GetCurrentPosition(&v59, v34),
                          v36 = Globals.GetArTime(),
                          v37 = pFrom.GetCurrentPosition(&v61, v36),
                          nDamageFlagh->end.y * 12.0 < ArPosition::GetDistance(v37, v35)) )
                        goto LABEL_100;
                    nPrevHP = pFrom.m_nHP;
                    nPrevMP = pFrom.m_nMP;
                    nDamageFlage = 26;
                    if ( LOBYTE(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)[1].end.z) )
                        nDamageFlage = 30;
                    if ( LOWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.face)
                      && (!damageType || damageType == 1 || damageType == 4 || damageType == 2) )
                    {
                        nReflectDamagef = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        v38 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        &v63 = pFrom.DealDamage(this,
                            LOWORD(v38->end.face),
                            SLODWORD(nReflectDamagef->end.z),
                            DT_ADDITIONAL_MAGICAL_DAMAGE,
                            0,
                            0,
                            nDamageFlage,
                            0,
                            0);
                    }
                    nFlaga = real_damage;
                    nReflectDamagea = (*&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end_time
                                     * nFlaga);
                    if ( nReflectDamagea && (damageType == DamageType.NormalPhysical || damageType == DamageType.NormalPhysicalLeftHand) )
                    {
                        v39 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        &WeaponIndices[2] = pFrom.DealDamage(this,
                            nReflectDamagea,
                            SLODWORD(v39->end.z),
                            0,
                            0,
                            0,
                            nDamageFlage,
                            0,
                            0);
                    }
                    nReflectDamageb = (std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)[1].end.x
                                     * nFlaga);
                    if ( nReflectDamageb && damageType == DamageType.NormalPhysicalSkill)
                    {
                        v40 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        &v57 = pFrom.DealPhysicalSkillDamage(this,
                            nReflectDamageb,
                            SLODWORD(v40->end.z),
                            0,
                            0,
                            nDamageFlage);
                    }
                    nReflectDamagec = (std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)[1].end.y
                                     * nFlaga);
                    if (nReflectDamagec != 0 && damageType == DamageType.NormalMagical)
                    {
                        v41 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        &v57 = pFrom.DealMagicalSkillDamage(this, nReflectDamagec, SLODWORD(v41->end.z), 0, 0, nDamageFlage);
                    }
 */
            nPrevHP = pFrom.m_nHP;
            nPrevMP = pFrom.m_fMP;

                    Messages.BroadcastHPMPMsg(pFrom, pFrom.m_nHP - nPrevHP, pFrom.m_fMP - nPrevMP, false);
                    if (this.IsPlayer())
                    {
                        Messages.SendHPMPMsg(this as Player, pFrom, pFrom.m_nHP - nPrevHP, pFrom.m_fMP - nPrevMP, true);
                    }
                    else if (this.IsSummon())
                    {
                        Summon s = this as Summon;
                        if(s != null && s.m_master != null)
                            Messages.SendHPMPMsg(s.m_master, pFrom, pFrom.m_nHP - nPrevHP, pFrom.m_fMP - nPrevMP, true);
                    }
//        LABEL_94:
                    if (pFrom.IsPlayer())
                    {
//        LABEL_99:
                        Messages.SendHPMPMsg(pFrom as Player, pFrom, pFrom.m_nHP - nPrevHP, pFrom.m_fMP - nPrevMP, true);
                    }
                    if (pFrom.IsSummon())
                    {
                        Summon s = pFrom as Summon;
                        if(s != null && s.m_master != null)
                            Messages.SendHPMPMsg(s.m_master, pFrom, pFrom.m_nHP - nPrevHP, pFrom.m_fMP - nPrevMP, true);
                    }
/*        LABEL_100:
                }
            }
*/
            result.nDamage = real_damage;
            return result;
        }

        public Damage CalcDamage(Creature pTarget, DamageType damage_type, float nDamage, Elemental.Type elemental_type, int accuracy_bonus, float critical_amp, int critical_bonus, int nFlag)
        {
            int nPercentage; // [sp+3Ch] [bp-14h]@31
            float nAccuracy; // [sp+44h] [bp-Ch]@31
            int nRandomDamage; // [sp+48h] [bp-8h]@31
            float fDefAdjustc; // [sp+5Ch] [bp+Ch]@57
            int fDefAdjust; // [sp+5Ch] [bp+Ch]@57
            float fDefAdjusta; // [sp+5Ch] [bp+Ch]@62
            int fDefAdjustb; // [sp+5Ch] [bp+Ch]@79
            char fDefAdjust_3; // [sp+5Fh] [bp+Fh]@16
            int nDamagec; // [sp+64h] [bp+14h]@8
            int nDamagea; // [sp+64h] [bp+14h]@8
            float nDamageb; // [sp+64h] [bp+14h]@55
            float nDamaged; // [sp+64h] [bp+14h]@90
            float nDefence; // [sp+6Ch] [bp+1Ch]@40
            int nDefencea; // [sp+6Ch] [bp+1Ch]@57

            bool bIsLeftHandDamage;
            bool bIsAdditionalDamage;
            bool bIsPhysicalDamage;
            bool bIsMagicalDamage;
            bool bDefAdjust;

            Damage result = new Damage();

            if (damage_type == DamageType.NormalMagical || damage_type == DamageType.StateMagical)
            {
                if(pTarget.IsMagicalImmune())
                {
                    result.bMiss = true;
                    result.nDamage = 0;
                    return result;
                }
            }
            else
            {
                if(pTarget.GetState(State.StateCode.Seal) != null)
                {
                    result.bMiss = true;
                    result.nDamage = 0;
                    return result;
                }
            }


            nDamagec = (int)(this.m_Expert[this.GetCreatureGroup()].fDamage * nDamage + nDamage);
            nDamagea = (int)pTarget.m_Expert[this.GetCreatureGroup()].fAvoid * nDamagec + nDamagec;

            bIsPhysicalDamage = damage_type == DamageType.NormalPhysical || damage_type == DamageType.NormalPhysicalLeftHand || damage_type == DamageType.StatePhysical || damage_type == DamageType.NormalPhysicalSkill;
            bIsMagicalDamage = damage_type == DamageType.NormalMagical || damage_type == DamageType.StateMagical;
            bIsAdditionalDamage = damage_type == DamageType.Additional || damage_type == DamageType.AdditionalLeftHand || damage_type == DamageType.AdditionalMagical;
            bIsLeftHandDamage = damage_type == DamageType.NormalPhysicalLeftHand || damage_type == DamageType.AdditionalLeftHand;
            bDefAdjust = damage_type == DamageType.StatePhysical || damage_type == DamageType.StateMagical;

            if ((nFlag & 2) == 0 && bIsPhysicalDamage && !bDefAdjust)
            {
                if ( bIsLeftHandDamage )
                    nAccuracy = this.m_Attribute.nAccuracyLeft;
                else
                    nAccuracy = this.m_Attribute.nAccuracyRight;

                nPercentage = 2 * ((44 - pTarget.GetLevel()) + this.GetLevel());
                if (nPercentage < 10)
                    nPercentage = 10;

                nPercentage = (int)(nAccuracy / pTarget.m_Attribute.nAvoid * (float)nPercentage + 7.0f + (float)accuracy_bonus);
                nAccuracy = pTarget.m_Attribute.nAvoid;
//                 if (Globals.GetRandomInt32() % 100 > nPercentage)
//                 {
//                     result.bMiss = true;
//                     result.nDamage = 0;
//                     return result;
//                 }
            }

            if ((nFlag & 2) == 0 && bIsMagicalDamage && !bDefAdjust)
            {
                nAccuracy = 2 * ((44 - pTarget.GetLevel()) + this.GetLevel());
                if (nAccuracy < 10)
                    nAccuracy = 10;
                if (Globals.GetRandomInt32() % 100 > (this.m_Attribute.nMagicAccuracy / pTarget.m_Attribute.nMagicAvoid * nAccuracy + 7.0f + accuracy_bonus))
                {
//        LABEL_105:
//                     result.bMiss = true;
// //        LABEL_6:
//                     result.nDamage = 0;
//                     return result;
                }
            }

            nRandomDamage = 0;
            nDefence = 0;
            if ( bIsAdditionalDamage && bDefAdjust)
            {
                fDefAdjusta = 1.0f;
                if ( bIsMagicalDamage && (this.m_Attribute.nMagicPoint < pTarget.m_Attribute.nMagicDefence))
                {
                    if (pTarget.m_Attribute.nMagicDefence <= 0 )
                        fDefAdjusta = 1;
                    else
                        fDefAdjusta = pTarget.m_Attribute.nMagicDefence;
                    fDefAdjusta = 1.0f - ((pTarget.m_Attribute.nMagicDefence - this.m_Attribute.nMagicPoint) / (2 * fDefAdjusta));
                }
                else if (bIsPhysicalDamage && (this.m_Attribute.nAttackPointRight < pTarget.m_Attribute.nDefence))
                {
                    if (pTarget.m_Attribute.nDefence <= 0 )
                        fDefAdjusta = 1;
                    else
                        fDefAdjusta = pTarget.m_Attribute.nDefence;
                    fDefAdjusta = 1.0f - ((pTarget.m_Attribute.nDefence - this.m_Attribute.nAttackPointRight) / (2 * fDefAdjusta));
                }

                fDefAdjust = (int)((float)nDamagea * fDefAdjusta);

            }
            else
            {
                fDefAdjust = nDamagea;

                if (!this.IsSkillProp())
                {
                    if ((nFlag & 4) == 0)
                    {
                        if (bIsPhysicalDamage)
                        {
                            nDefence = pTarget.m_Attribute.nDefence;
                            if ((pTarget.IsWearShield() || pTarget.IsSummon()) && Globals.GetRandomInt32() % 100 < pTarget.m_Attribute.nBlockChance)
                            {
                                if (Globals.GetRandomInt32() % 100 < 20)
                                {
                                    result.bPerfectBlock = true;
                                    result.nDamage = 0;
                                    return result;
                                }
                                nDefence += pTarget.m_Attribute.nBlockDefence;
                                result.bBlock = true;
                            }
                        }
                        else
                        {
                            if (bIsMagicalDamage)
                                nDefence = pTarget.m_Attribute.nMagicDefence;
                        }
                    }

                    nDamageb = 1.0f - 0.4f * nDefence / nDamagea;
                    if (nDamageb < 0.3f)
                        nDamageb = 0.3f;

                    fDefAdjustc = 1.0f - nDefence * 0.5f / nDamagea;
                    if (fDefAdjustc < 0.05f)
                        fDefAdjustc = 0.05f;

                    nDefencea = this.GetLevel();
                    fDefAdjust = (int)((float)nDefencea * 1.7f * nDamageb + nDamagea * fDefAdjustc);
                    if (fDefAdjust < 1)
                        fDefAdjust = 1;
                }
                if (!GameContent.g_bIgnoreRandomDamage)
                {
                    nRandomDamage = Globals.GetRandomInt32((int)(-((float)fDefAdjust * 0.05f)), (int)(((float)fDefAdjust * 0.05f)));
                }
            }


            fDefAdjustb = (fDefAdjust + nRandomDamage);
            if (!bIsAdditionalDamage )
            {
                if ((nFlag & 0x10) == 0)
                {
                    int cd = this.GetCriticalDamage(fDefAdjustb, critical_amp, critical_bonus);
                    if (cd != 0)
                    {
                        fDefAdjustb += cd;
                        result.bCritical = true;
                    }
                }
            }
            if ( (damage_type == DamageType.Additional || damage_type == DamageType.AdditionalLeftHand) && (this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
            {
                if ( bIsLeftHandDamage )
                    fDefAdjustb = (int)(fDefAdjustb * (float)this.m_nDoubleWeaponMasteryLevel * 0.02f + 0.44f);
                else
                    fDefAdjustb *= (int)(fDefAdjustb * (float)this.m_nDoubleWeaponMasteryLevel * 0.001f + 0.9f);
            }
           
            nDamaged = 1.0f - (pTarget.m_Resist.nResist[(int)elemental_type] / 300);
            result.nDamage = (int)(nDamaged * (float)fDefAdjustb);
            result.nResistedDamage = fDefAdjustb - result.nDamage;

            if((pTarget.IsPlayer() || pTarget.IsSummon()) && !ReferenceEquals(this, pTarget))
            {
                if (this.IsPlayer())
                    result.nDamage = (int)((float)result.nDamage * GameRule.fPVPDamageRateForPlayer);
                else if (this.IsSummon())
                    result.nDamage = (int)((float)result.nDamage * GameRule.fPVPDamageRateForSummon);
            }

            if ( bIsMagicalDamage && !bIsAdditionalDamage && fDefAdjustb < 1 )
                result.nDamage = 1;
            return result;
        }

        public int GetCriticalDamage(int damage, float critical_amp, int critical_bonus)
        {
            int result;

            if (this.m_Attribute.nCritical * critical_amp + critical_bonus < Globals.GetRandomInt32(0, 99))
                result = 0;
            else
                result = (int)(this.m_Attribute.nCriticalPower / 100.0f * (float)damage);
            return result;
        }

        public virtual bool StartAttack(uint target, bool bNeedFastReaction)
        {
            bool result;

            if (this.m_nHP == 0)// || this.m_hEnemy != 0)
            {
                result = false;
            }
            else
            {
                this.m_hEnemy = target;
                this.m_StatusFlag &= ~StatusFlags.AttackStarted;

                RappelzServer.Instance.SetObjectPriority(this, SchedulerObject.Priority.Highest);
                if (this.IsUsingBow() || this.IsUsingCrossBow() && this.IsPlayer())
                    this.m_nNextAttackMode = 1;
                if (bNeedFastReaction)
                    this.onAttackAndSkillProcess();
                result = true;
            }
            return result;
        }


        public virtual void CancelAttack()
        {
            Creature.AttackInfo[] info = new Creature.AttackInfo[4];

            if ((this.IsUsingBow()) || this.IsUsingCrossBow() && (this.IsPlayer() && this.m_nNextAttackMode == 0))
            {
                this.m_nNextAttackMode = 1;
                this.SetNextAttackableTime(Globals.GetArTime());
            }
            if ((this.m_StatusFlag & StatusFlags.AttackStarted) != 0)
            {
                Creature.get(this.m_hEnemy);
                for (int i = 3; i >= 0; --i)
                {
                    info[i] = new Creature.AttackInfo();
                }
                this.broadcastAttackMessage(Creature.get(this.m_hEnemy) as Creature, info, 0, 0, false, false, false, true);
            }
            this.m_hEnemy = 0;
            this.m_StatusFlag |= StatusFlags.FirsAttack;

        }

        public void EndAttack()
        {
            Creature.AttackInfo[] info = new Creature.AttackInfo[4];

            uint ct = Globals.GetArTime();

            if (this.IsUsingBow() || this.IsUsingCrossBow() && this.IsPlayer() && this.m_nNextAttackMode == 0)
            {
                this.m_nNextAttackMode = 1;
                this.SetNextAttackableTime(ct);
            }
            if ((this.m_StatusFlag & StatusFlags.AttackStarted) != 0)
            {
                Creature target = Creature.get(this.m_hEnemy) as Creature;
                for (int i = 0; i < 4; ++i)
                {
                    info[i] = new Creature.AttackInfo();
                }
                if (this.IsPlayer() || this.IsSummon())
                {
                    if (target != null)
                        this.broadcastAttackMessage(target, info, 0, 0, false, false, true, false);
                }
            }
            this.m_hEnemy = 0;
            this.m_StatusFlag |= StatusFlags.FirsAttack;

        }
        // Function       :   public bool IsAttacking()
        // Function       :   public unsigned int GetEnemyHandle()
        // Function       :   public void StructCreature::onAttack(struct StructCreature *, int)

        public virtual int onDamage(Creature pFrom, Elemental.Type elementalType, Creature.DamageType damageType, int nDamage, bool bCritical)
        {
            return nDamage;
        }


        public virtual bool IsBattleMode()
        {
            return false;
        }
        
        public void AddHateToEnemyList(uint handle, int pt)
        {

        }


        public bool AddToEnemyList(uint handle)
        {
            lock (this.m_vEnemyList)
            {
                if (this.m_vEnemyList.Contains(handle))
                    return false;
                this.m_vEnemyList.Add(handle);
            }
            return true;
        }

        public bool RemoveFromEnemyList(uint handle)
        {
            if (this.m_vEnemyList.Contains(handle))
            {
                this.m_vEnemyList.Remove(handle);
                return true;
            }
            return false;
        }
        // Function       :   public unsigned int GetEnemyCount()

        public void RemoveAllHate()
        {

        }

        public virtual CreatureStat GetBaseStat()
        {
            return baseStat;
        }
        // Function       :   public const struct CreatureStat & GetStat()
        // Function       :   public const struct CreatureAttributeServer & GetAttribute()
        // Function       :   public const struct CreatureStat & GetStatByState()
        // Function       :   public const struct CreatureAttributeServer & GetAttributeByState()
        // Function       :   public int GetHPRegenPercentage()
        // Function       :   public int GetHPRegenPoint()
        // Function       :   public int GetMPRegenPercentage()
        // Function       :   public int GetMPRegenPoint()

        public ItemBase.ItemClass GetWeaponClass()
        {
            ItemBase.ItemClass result = ItemBase.ItemClass.ClassEtc;
            Item itemRight = this.GetWornItem(ItemBase.ItemWearType.WearRightHand);

            if (itemRight != null)
            {
                if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                {
                    Item itemLeft = this.GetWornItem(ItemBase.ItemWearType.WearLeftHand);
                    result = itemRight.m_pItemBase.nClass;
                    if (itemRight.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandSword && itemLeft.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandSword)
                        return ItemBase.ItemClass.ClassDoubleSword;
                    if (itemRight.m_pItemBase.nClass == ItemBase.ItemClass.ClassDagger && itemLeft.m_pItemBase.nClass == ItemBase.ItemClass.ClassDagger)
                        return ItemBase.ItemClass.ClassDoubleDagger;
                    if (itemRight.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandAxe && itemLeft.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandAxe)
                        return ItemBase.ItemClass.ClassDoubleAxe;
                }
                result = itemRight.m_pItemBase.nClass;
            }
            return result;
        }
        // Function       :   public enum ItemBase::ItemClass StructCreature::GetArmorClass()

        public virtual int GetCreatureGroup()
        {
            return 0;
        }
        // Function       :   public int GetStrength()
        // Function       :   public int GetVital()
        // Function       :   public int GetDexterity()
        // Function       :   public int GetAgility()
        // Function       :   public int GetIntelligence()
        // Function       :   public int GetMentality()
        // Function       :   public int GetLuck()
        public virtual float GetFCM()
        {
            return 1.0f;
        }
        // Function       :   public float GetWeight()
        // Function       :   public int GetCritical()
        // Function       :   public int GetCriticalPower()

        public int GetAttackPointRight(Elemental.Type type, bool bPhysical, bool bBad)
        {
            float v4; // st7@3
            float v5; // st6@3

            if (bPhysical)
            {
                if (bBad)
                {
                    v4 = this.m_BadPhysicalElementalSkillStateMod[(int)type].fPhysicalDamage;
                    v5 = this.m_Attribute.nAttackPointRight;
                }
                else
                {
                    v4 = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fPhysicalDamage;
                    v5 = this.m_Attribute.nAttackPointRight;
                }
            }
            else
            {
                if (bBad)
                {
                    v4 = this.m_BadMagicalElementalSkillStateMod[(int)type].fPhysicalDamage;
                    v5 = this.m_Attribute.nAttackPointRight;
                }
                else
                {
                    v4 = this.m_GoodMagicalElementalSkillStateMod[(int)type].fPhysicalDamage;
                    v5 = this.m_Attribute.nAttackPointRight;
                }
            }
            return (int)(v4 * v5);
        }

        // Function       :   public int GetAttackPointRight()
        // Function       :   public int GetAttackPointLeft()
        // Function       :   public int GetDefence()

        public int GetMagicPoint(Elemental.Type type, bool bPhysical, bool bBad)
        {
            float v4;
            float v5;

            if (bPhysical)
            {
                if (bBad)
                {
                    v4 = this.m_BadPhysicalElementalSkillStateMod[(int)type].fMagicalDamage;
                    v5 = this.m_Attribute.nMagicPoint;
                }
                else
                {
                    v4 = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fMagicalDamage;
                    v5 = this.m_Attribute.nMagicPoint;
                }
            }
            else
            {
                if (bBad)
                {
                    v4 = this.m_BadMagicalElementalSkillStateMod[(int)type].fMagicalDamage;
                    v5 = this.m_Attribute.nMagicPoint;
                }
                else
                {
                    v4 = this.m_GoodMagicalElementalSkillStateMod[(int)type].fMagicalDamage;
                    v5 = this.m_Attribute.nMagicPoint;
                }
            }
            return (int)(v4 * v5);
        }
        // Function       :   public int GetMagicPoint()
        // Function       :   public int GetMagicDefence()
        // Function       :   public int GetAccuracyRight()
        // Function       :   public int GetAccuracyLeft()
        // Function       :   public int GetMagicAccuracy()
        // Function       :   public int GetAvoid()
        // Function       :   public int GetMagicAvoid()
        // Function       :   public int GetBlockChance()
        // Function       :   public int GetBlockDefence()

        public virtual float GetMoveSpeed()
        {
            return this.m_Attribute.nMoveSpeed;
        }

        // Function       :   public int GetAttackSpeed()
        // Function       :   public int GetMaxWeight()
        // Function       :   public int GetCastingSpeed()

        public float GetCastingMod(Elemental.Type type, bool bPhysical, bool bBad, uint nOriginalCoolTime)
        {
            return 1.0f;
            /*
                        char *v5; // eax@3
                        double v6; // st7@4
                        char *v7; // eax@5
                        char *v8; // eax@8
                        char *v9; // eax@10
                        float result; // st7@13

                        if (bPhysical)
                        {
                            if ( bBad )
                                result = this.m_BadPhysicalElementalSkillStateMod[(int)type].fManaCostRatio;
                            else
                                result = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fManaCostRatio;
                        }
                        else
                        {
                            if ( bBad )
                                if(this.m_BadMagicalElementalSkillStateMod[(int)type].fCooltime > (float)nOriginalCoolTime)
                                    return this.m_BadMagicalElementalSkillStateMod[(int)type].

                            else
                                result = this.m_GoodMagicalElementalSkillStateMod[(int)type].fManaCostRatio;
                        }


                        if ( !bPhysical )
                        {
                            if ( bBad )
                            {
                                v8 = this + 76 * type;
                                if (this. *(v8 + 820) >= nOriginalCoolTime )
                                {
                                    v6 = *(v8 + 812);
                                    goto LABEL_13;
                                }
                            }
                            else
                            {
                                v9 = this + 76 * type;
                                if ( *(v9 + 687) >= nOriginalCoolTime )
                                {
                                    v6 = *(v9 + 679);
                                    goto LABEL_13;
                                }
                            }
                            goto LABEL_12;
                        }
                        if ( !bBad )
                        {
                            v7 = this + 76 * type;
                            if ( *(v7 + 421) >= nOriginalCoolTime )
                            {
                                v6 = *(v7 + 413);
                                goto LABEL_13;
                            }
                    LABEL_12:
                            v6 = 1.0;
                            goto LABEL_13;
                        }
                        v5 = this + 76 * type;
                        if ( *(v5 + 554) < nOriginalCoolTime )
                            goto LABEL_12;
                        v6 = *(v5 + 546);
                    LABEL_13:
                        LODWORD(result) = LODWORD(v6);
                        return result;
            */
        }


        public float GetManaCostRatio(Elemental.Type type, bool bPhysical, bool bBad)
        {
            float result;

            if (bPhysical)
            {
                if (bBad)
                    result = this.m_BadPhysicalElementalSkillStateMod[(int)type].fManaCostRatio;
                else
                    result = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fManaCostRatio;
            }
            else
            {
                if (bBad)
                    result = this.m_BadMagicalElementalSkillStateMod[(int)type].fManaCostRatio;
                else
                    result = this.m_GoodMagicalElementalSkillStateMod[(int)type].fManaCostRatio;
            }
            return result;
        }


        public float GetCoolTimeMod(Elemental.Type type, bool bPhysical, bool bBad)
        {
            float result;

            if (bPhysical)
            {
                if (bBad)
                    result = this.m_BadPhysicalElementalSkillStateMod[(int)type].fCooltime;
                else
                    result = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fCooltime;
            }
            else
            {
                if (bBad)
                    result = this.m_BadMagicalElementalSkillStateMod[(int)type].fCooltime;
                else
                    result = this.m_GoodMagicalElementalSkillStateMod[(int)type].fCooltime;
            }
            return result;
        }


        public float GetCoolTimeSpeed()
        {
            return this.m_Attribute.nCoolTimeSpeed / 100.0f;
        }

        public virtual float GetItemChance()
        {
            return this.m_Attribute.nItemChance;
        }
        // Function       :   public float GetCreatureCardChance()
        // Function       :   public int GetElementalResist(enum Elemental::Type)
        
        public float GetMagicalHateMod(Elemental.Type type, bool bPhysical, bool bBad)
        {
            float result = 0;

            if ( bPhysical )
            {
                if ( bBad )
                    result = this.m_BadPhysicalElementalSkillStateMod[(int)type].fHate;
                else
                    result = this.m_GoodPhysicalElementalSkillStateMod[(int)type].fHate;
            }
            else
            {
                if ( bBad )
                    result = this.m_BadMagicalElementalSkillStateMod[(int)type].fHate;
                else
                    result = this.m_GoodMagicalElementalSkillStateMod[(int)type].fHate;
            }
            return result;
        }


        public RappelzPair<float, int> GetHateMod(int nHateModType, bool bIsHarmful)
        {
            RappelzPair<float, int> result = new RappelzPair<float, int>();
            float fAmpValue = 1.0f;
            int nIncValue = 0;

            foreach (HateModifier hm in this.m_vHateMod)
            {
                if (bIsHarmful)
                {
                    if (!hm.bIsApplyToHarmful)
                        continue;
                }
                else
                {
                    if (!hm.bIsApplyToHelpful)
                        continue;
                }

                if ((nHateModType == 1 && hm.bIsApplyToPhysicalSkill) || (nHateModType == 2 && hm.bIsApplyToMagicalSkill) || (nHateModType == 3 && hm.bIsApplyToPhysicalAttack))
                {
                    fAmpValue += hm.fAmpValue;
                    nIncValue += hm.nIncValue;
                }
            }

            result.Second = nIncValue;
            result.First = fAmpValue;
            return result;
        }


        public virtual float GetScale()
        {
            return 1.0f;
        }

        public virtual float GetSize()
        {
            return 1.0f;
        }

        public float GetUnitSize()
        {
            return (this.GetSize() * 12) * this.GetScale();
        }

        public uint GetAttackInterval()
        {
            return (uint)(100.0f / this.m_Attribute.nAttackSpeed * 115.0f);
        }

        public float GetRealAttackRange()
        {
            return (12 * this.m_Attribute.nAttackRange) / 100.0f;
        }
        // Function       :   public unsigned char GetRealMoveSpeed()
        // Function       :   public int StructCreature::GetAttackPointRightWithoutWeapon(enum Elemental::Type, bool, bool)
        // Function       :   public int GetAttackPointRightWithoutWeapon()
        // Function       :   public int GetAttackPointLeftWithoutWeapon()

        public uint GetBowAttackInterval()
        {
            return (uint)((float)this.GetAttackInterval() * (1.0f - this.m_fBowInterval));
        }

        public uint GetBowInterval()
        {
            return (uint)((float)this.GetAttackInterval() * this.m_fBowInterval);
        }

        public virtual void OnUpdate()
        {
            uint ct = Globals.GetArTime();
            if ((this.m_StatusFlag & StatusFlags.NeedToCalculateStat) != 0)
            {
                this.CalculateStat();
                this.m_StatusFlag &= ~StatusFlags.NeedToCalculateStat;
            }
            if (this.m_nEnergy != 0)
            {
                int start = this.m_nEnergyStartPos;
                uint energy = this.m_arEnergy[start];
                int count = 0;
                if (energy < ct)
                {
                    do
                    {
                        if (energy == 0)
                            break;
                        if (energy == this.m_nEnergy)
                            break;
                        start = (start + 1) % 10;
                        ++count;
                        energy = this.m_arEnergy[start];
                    }
                    while (energy < ct);
                    if (count != 0)
                        this.RemoveEnergy(count);
                }
            }
            this.regenHPMP(ct);

            if ((this.m_StatusFlag & StatusFlags.HavocBurst) != 0 && ct - this.m_nLastHavocUpdateTime > 100)
            {
                State havoc = this.GetState(State.StateCode.HavocBurst);
                if (havoc != null)
                {
                    double lhv = (double)(int)((double)havoc.GetValue(6) * (double)this.m_nMaxHavoc / 100.0);
                    uint lct = ct - this.m_nLastHavocUpdateTime;

                    double flct = (double)lct;
                    if (lct < 0)
                        flct += 4294967300.0;
                    this.SetHavoc(this.m_nHavoc - (int)(lhv * flct / 1000.0));
                    this.m_nLastHavocUpdateTime = ct;
                }
                else
                {
                    this.m_StatusFlag &= ~StatusFlags.HavocBurst;
                }
            }
            if (this.m_vAura.Count > 0)
            {
                for (int i = m_vAura.Count - 1; i >= 0; i--)
                {
                    RappelzPair<int, Skill> sp = m_vAura[i];
                    if (sp.Second.m_nAuraRefreshTime + 700 <= ct)
                    {
                        if (this.onProcAura(sp.Second, sp.First))
                        {
                            sp.Second.m_nAuraRefreshTime = ct;
                        }
                        else
                        {
                            //                            TS_SC_AURA.TS_SC_AURA();
                            //                          msg.caster = this.GetHandle();
                            //                        msg.skill_id = sp.First;
                            //                      msg.status = 0;
                            // Data           :   this+0x7, Member, Type: unsigned int, caster
                            // Data           :   this+0xB, Member, Type: unsigned short, skill_id
                            // Data           :   this+0xD, Member, Type: bool, status

                            if (this.IsPlayer())
                            {
                                //                                PendMessage(this, msg);
                            }
                            if (this.IsSummon())
                            {
                                Summon s = (Summon)this;
                                if (s.m_master != null && s.m_master.bIsInWorld)
                                {
                                    //                                  PendMessage(s.m_master, msg);
                                }
                            }
                            m_vAura.RemoveAt(i);
                        }

                    }
                }
            }

            if (this.bIsInWorld)
            {
                ArPosition fpos = new ArPosition();
                if (this.m_nPendedClearStateFlag != 0)
                {
                    this.removeStateWithFlag(this.m_nPendedClearStateFlag);
                    this.m_nPendedClearStateFlag = 0;
                }
                if (m_vStateList.Count > 0 && this.m_nLastStateProcTime + 100 < ct)
                {
                    this.procStateDamage(ct);
                    this.procState(ct);
                    if (this.ClearExpiredState(ct))
                        this.CalculateStat();
                    this.m_nLastStateProcTime = ct;
                }
                if ((this.m_StatusFlag & StatusFlags.Feared) != 0)
                {
                    if (!this.mv.IsMoving(ct) || (this.m_StatusFlag & StatusFlags.MovingByFear) == 0)
                    {
                        State fear = this.GetState(State.StateCode.Fear);
                        if (fear != null)
                        {
                            int fvi = (int)fear.GetValue(1);
                            int rdi = Globals.GetRandomInt32() % 628;
                            float rdf = (float)(rdi - 20) / 100.0f;
                            fpos.x = (float)Math.Sin(rdf) * 120.0f + this.mv.x;
                            fpos.y = (float)Math.Cos(rdf) * 120.0f + this.mv.x;
                            if ((this.m_StatusFlag & StatusFlags.MovingByFear) == 0)
                            {
                                this.m_StatusFlag |= StatusFlags.MovingByFear;
                                Creature source = (Creature)GameObject.get(fear.m_hCaster[0]);
                                if (source != null)
                                {
                                    ArPosition spos = new ArPosition();
                                    spos.x = source.mv.x;
                                    spos.y = source.mv.y;
                                    spos.z = source.mv.z;
                                    spos.face = source.mv.face;

                                    ArPosition cpos = this.GetCurrentPosition(ct);
                                    float dist = cpos.GetDistance(spos);
                                    if (dist > 0.0f)
                                    {
                                        fpos.x = (spos.x - cpos.x) * 120.0f / dist + cpos.x;
                                        fpos.y = (spos.y - cpos.y) * 120.0f / dist + cpos.y;
                                    }
                                }
                            }

                            for (int i = 0; i < 9; ++i)
                            {
                                if (!GameContent.IsBlocked(fpos.x, fpos.y))
                                    break;
                                int rnd = Globals.GetRandomInt32() % 628;
                                float rndf = (float)rnd / 100.0f;
                                fpos.x = (float)Math.Sin(rndf * 120.0 + (float)this.mv.x);
                                fpos.y = (float)Math.Cos(rndf * 120.0 + (float)this.mv.y);
                            }

                            if ((float)GameContent.g_nMapWidth < (double)fpos.x)
                                fpos.x = (float)GameContent.g_nMapWidth;
                            if ((float)GameContent.g_nMapHeight < (double)fpos.y)
                                fpos.y = (float)GameContent.g_nMapHeight;
                            if (fpos.x < 0.0f)
                                fpos.x = 0.0f;
                            if (fpos.y < 0.0f)
                                fpos.y = 0.0f;
                            if (this.bIsInWorld)
                            {
                                if (!GameContent.IsBlocked(fpos.x, fpos.y))
                                {
                                    int mspeed = (int)this.GetMoveSpeed();
                                    if ((mspeed / 7) != 0)
                                    {
                                        mspeed = mspeed + fvi / 7;
                                        RappelzServer.Instance.SetMove(this, this.mv, fpos, (sbyte)mspeed, true, ct, true);
                                    }
                                }
                            }
                        }
                    }
                }
                if (this.m_bNeedToBroadcastStatusFlag)
                {
                    this.m_bNeedToBroadcastStatusFlag = false;
                    Messages.BroadcastStatusMessage(this);
                }
            }

        }
        // Function       :   public unsigned short AllocStateUID()
        public ushort AddState(State.StateType type, State.StateCode code, uint caster, int level, uint start_time, uint end_time, bool bIsAura, int nStateValue, string szStateValue)
        {
            List<ushort> vDeleteStateUID = new List<ushort>();      // -220 -0DCh
            // .text:0043866B itCaster        = StructCreature::iterator ptr -0CCh
            // .text:0043866B _Right          = std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > ptr -0C4h
            // .text:0043866B var_BC          = dword ptr -0BCh
            int base_damage;                                        // -184 -0B8h
            // .text:0043866B this            = std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > ptr -0B4h
            // .text:0043866B result          = StructCreature::iterator ptr -0ACh
            bool bNotErasable;                                      // -162 -0A2h
            bool bAlreadyExist;                                     //   = byte ptr -0A1h
            // .text:0043866B it              = std::_Vector_iterator<StructState,std::allocator<StructState> > ptr -0A0h
            // .text:0043866B var_98          = dword ptr -98h
            // .text:0043866B var_90          = dword ptr -90h
            // .text:0043866B state           = StructState ptr -8Ch
            // .text:0043866B var_4           = dword ptr -4
            // .text:0043866B type            = dword ptr  8
            // .text:0043866B code            = dword ptr  0Ch
            // .text:0043866B caster          = dword ptr  10h
            // .text:0043866B level           = dword ptr  14h
            // .text:0043866B start_time      = dword ptr  18h
            // .text:0043866B end_time        = dword ptr  1Ch
            // .text:0043866B bIsAura         = dword ptr  20h
            // .text:0043866B nStateValue     = dword ptr  24h
            // .text:0043866B szStateValue    = dword ptr  28h
            // 
            // Data           :   ebp Relative, [00000094], Param, Type: enum StructState::StateType, type
            // Data           :   ebp Relative, [00000098], Param, Type: enum StructState::StateCode, code
            // Data           :   ebp Relative, [0000009C], Param, Type: unsigned int, caster
            // Data           :   ebp Relative, [000000A0], Param, Type: int, level
            // Data           :   ebp Relative, [000000A4], Param, Type: unsigned long, start_time
            // Data           :   ebp Relative, [000000A8], Param, Type: unsigned long, end_time
            // Data           :   ebp Relative, [000000AC], Param, Type: bool, bIsAura
            // Data           :   ebp Relative, [000000B0], Param, Type: int, nStateValue
            // Data           :   ebp Relative, [000000B4], Param, Type: const char *, szStateValue
            // Data           :   ebp Relative, [FFFFFFEA], Local, Type: bool, bNotErasable
            // Data           :   ebp Relative, [FFFFFFB0], Local, Type: class std::vector<unsigned short,std::allocator<unsigned short> >, vDeleteStateUID
            // Data           :   ebp Relative, [FFFFFFD4], Local, Type: int, base_damage
            // Data           :   ebp Relative, [FFFFFFEB], Local, Type: bool, bAlreadyExist
            // Data           :   ebp Relative, [FFFFFFC0], Local, Type: struct StructCreature::iterator, itCaster
            // Data           :   ebp Relative, [FFFFFFEC], Local, Type: class std::_Vector_iterator<StructState,std::allocator<StructState> >, it
            // Data           :   ebp Relative, [FFFFFFDC], Local, Type: int, i
            // Data           :   ebp Relative, [FFFFFFD8], Local, Type: class std::_Vector_iterator<unsigned short,std::allocator<unsigned short> >, dit
            // Data           :   ebp Relative, [00000000], Local, Type: struct StructState, state
            StateInfo stateInfo;
            Creature pCaster;
            int i;

            this.m_StatusFlag |= StatusFlags.NeedToUpdateState;
            stateInfo = GameContent.GetStateInfo((int)code);
            if (stateInfo == null)
            {
                // not a valid state, boot them I guess
                //                 v14 = GameObject.raw_get(caster);
                //                 if (v14 != null)
                //                 {
                //                     if (v14.IsPlayer())
                //                     {
                //                         if ( *&v14[22].baseclass_0.baseclass_0.m_bIsEnable )
                //                             (*(**&v14[22].baseclass_0.baseclass_0.m_bIsEnable + 8))();
                //                     }
                //                 }
                return 1;
            }
            if (this.m_nHP == 0 && (stateInfo.state_time_type & 0x81) != 0)
                return 5;

            Monster mob = this as Monster;
            Player player = this as Player;
            Summon summon = this as Summon;


            if ((stateInfo.state_time_type & 8) != 0
              && this.IsMonster()
              && mob.IsBossMonster())
                return 26;
            if (code == State.StateCode.Fear)
            {
                if (this.IsMonster()
                  && mob.IsDungeonConnector() || mob.IsAutoTrap())
                    return 26;
            }
            else
            {
                if (code != State.StateCode.Sleep)
                {
                    if (code != State.StateCode.Nightmare)
                    {
                        if (code != State.StateCode.Seal)
                        {
                            if (code != State.StateCode.ShineWall)
                            {
                                if (code != State.StateCode.Stun)
                                {
                                    if (stateInfo.effect_type != 104)
                                    {
                                        if (stateInfo.effect_type != 82
                                          || stateInfo.fValue[0] == 0.0f
                                          && stateInfo.fValue[1] == 0.0f
                                          && stateInfo.fValue[2] == 0.0f
                                          && stateInfo.fValue[3] == 0.0f)
                                            goto LABEL_40;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (this.m_pCastSkill != null)
                this.CancelSkill();

            if (this.IsPlayer() && (player.m_nRideIdx != 0 || player.m_nRidingStateUid != 0))
            {
                player.UnMount(1);
            }
            else if (this.IsSummon())
            {
                if (summon.m_master.m_nRideIdx != 0 || summon.m_master.m_nRidingStateUid != 0)
                {
                    summon.m_master.UnMount(1);
                }
            }

        LABEL_40:
            if (stateInfo.effect_type == 200)
            {
                if ((this.m_StatusFlag & StatusFlags.Hiding) != 0)
                    this.RemoveState(State.StateCode.Hide, 65535);
            }
            if (code == State.StateCode.Fear)
                this.m_StatusFlag &= ~StatusFlags.MovingByFear;

            pCaster = Creature.get(caster) as Creature;
            base_damage = 0;
            if (pCaster != null && stateInfo.base_effect_id > 0)
            {
                if (stateInfo.base_effect_id <= 2)
                    base_damage = pCaster.GetAttackPointRight((Elemental.Type)stateInfo.elemental_type, true, true);
                else if (stateInfo.base_effect_id <= 4)
                    base_damage = pCaster.GetMagicPoint((Elemental.Type)stateInfo.elemental_type, false, true);
                else if (stateInfo.base_effect_id == 6)
                    base_damage = pCaster.GetAttackPointRight((Elemental.Type)stateInfo.elemental_type, true, true);
                else if ((stateInfo.base_effect_id - 11) <= 1)
                    base_damage = pCaster.GetMagicPoint((Elemental.Type)stateInfo.elemental_type, false, true);
            }

            bNotErasable = ((stateInfo.state_time_type >> 4) & 1) != 0;
            vDeleteStateUID.Clear();
            bAlreadyExist = false;

            foreach (State s in this.m_vStateList)
            {
                if (code == s.m_nCode)
                {
                    bAlreadyExist = true;
                }
                else
                {
                    bool bf = false;
                    for (i = 0; i < 3; ++i)
                    {
                        if (s.IsDuplicatedGroup(stateInfo.duplicate_group[i]))
                        {
                            bf = true;
                            break;
                        }
                    }
                    if (!bf)
                        continue;
                }

                if (bNotErasable != (((s.GetTimeType() >> 4) & 1) != 0))
                {
                    if (!bNotErasable)
                        return 9;
                    vDeleteStateUID.Add(s.m_nUID);
                }
                else
                {
                    if (s.GetLevel() > level)
                        return 9;

                    if (s.GetLevel() == level)
                    {
                        uint et = s.m_nEndTime[1];
                        if (s.m_nEndTime[0] > et)
                            et = s.m_nEndTime[0];
                        if (et > end_time)
                            return 9;
                    }
                    if (code != s.m_nCode)
                        vDeleteStateUID.Add(s.m_nUID);
                }
            }

            foreach (ushort id in vDeleteStateUID)
            {
                for (i = this.m_vStateList.Count - 1; i >= 0; --i)
                {
                    State s = this.m_vStateList[i];

                    if (id == s.m_nUID)
                    {
                        this.m_vStateList.RemoveAt(i);
                        this.CalculateStat();
                        break;
                    }
                }
            }
            if (bAlreadyExist)
            {
                foreach (State s in this.m_vStateList)
                {
                    if (code == s.m_nCode)
                    {
                        s.AddState(type, caster, (ushort)level, start_time, end_time, base_damage, bIsAura);
                        this.CalculateStat();
                        this.onUpdateState(s, false);
                        this.onAfterAddState(s);
                        break;
                    }
                }
            }
            else
            {
                this.m_nCurrentStateUID++;
                State ns = new State(type, code, this.m_nCurrentStateUID, caster, (ushort)level, start_time, end_time, base_damage, bIsAura, nStateValue, szStateValue);
                this.m_vStateList.Add(ns);
                this.CalculateStat();

                this.onUpdateState(ns, false);

                if (this.IsMonster())
                {
                    if (!this.IsMovable())
                    {
                        if (this.m_Attribute.nAttackRange < 84)
                            this.m_Attribute.nAttackRange = 83;
                    }
                }
                this.onAfterAddState(ns);
            }
            return 0;
        }

        public void RemoveState(State.StateCode code, int state_level)
        {
            for (int i = 0; i < this.m_vStateList.Count; ++i)
            {
                State s = this.m_vStateList[i];
                if (s.m_nCode == code)
                {
                    int level = s.GetLevel();
                    if (level <= state_level)
                    {
                        level = s.GetLevel();
                        if (level <= state_level)
                        {
                            this.onUpdateState(s, true);
                            this.m_vStateList.RemoveAt(i);
                            this.CalculateStat();
                            this.onAfterRemoveState(s);
                        }
                        return;
                    }
                }
            }
        }

        public void RemoveState(int uid)
        {
            for (int i = 0; i < this.m_vStateList.Count; ++i)
            {
                State s = this.m_vStateList[i];
                if (s.m_nUID == uid)
                {
                    this.onUpdateState(s, true);
                    this.m_vStateList.RemoveAt(i);
                    this.CalculateStat();
                    this.onAfterRemoveState(s);
                    return;
                }
            }
        }


        public void RemoveStatesOnDamaged()
        {
            /*
                        StructCreature *v1; // esi@1
                        char *v2; // edi@1
                        int v3; // eax@1
                        ArMoveVector::MOVE_INFO *v4; // eax@2
                        ArMoveVector::MOVE_INFO *v5; // eax@4
                        ArMoveVector::MOVE_INFO *v6; // eax@4
                        ArSchedulerObjectVtbl *v7; // edx@4
                        std::_Vector_iterator<StructState,std::allocator<StructState> > *v8; // eax@4
                        std::_Container_base *v9; // ecx@4
                        StructState *v10; // eax@4
                        ArSchedulerObjectVtbl *v11; // eax@4
                        std::_Vector_iterator<StructState,std::allocator<StructState> > result; // [sp+0h] [bp-24h]@4
                        std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > thisa; // [sp+8h] [bp-1Ch]@1
                        std::_Vector_iterator<StructState,std::allocator<StructState> > it; // [sp+10h] [bp-14h]@1
                        int v15; // [sp+20h] [bp-4h]@4
                        StructState state; // [sp+24h] [bp+0h]@1
                        unsigned int v17; // [sp+ACh] [bp+88h]@1

                        v17 = &state ^ __security_cookie;
                        v1 = this;
                        v2 = &this->m_vStateList;
                        std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                            &thisa,
                            this->m_vStateList._Myfirst,
                            &this->m_vStateList.baseclass_0.___u0.baseclass_0);
                        it.baseclass_0.baseclass_0.baseclass_0._Mycont = thisa.baseclass_0.baseclass_0._Mycont;
                        it.baseclass_0._Myptr = thisa._Myptr;
                        v3 = *(v2 + 2);
                        *&state.m_szStateValue[16] = v2;
                        for ( *&state.m_szStateValue[12] = v3; ; *&state.m_szStateValue[12] = *(v2 + 2) )
                        {
                            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                                &thisa,
                                *&state.m_szStateValue[12],
                                *&state.m_szStateValue[16]);
                            if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(&it, &thisa) )
                                break;
                            v4 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                            if ( StructState::GetTimeType(v4) & 0x40 )
                            {
                                v5 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                StructState::StructState(&state, v5);
                                v15 = 0;
                                v6 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                v7 = v1->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                *&state.m_szStateValue[16] = 1;
                                *&state.m_szStateValue[12] = v6;
                                (v7[19].IsDeleteable)(v1, v6, 1);
                                v8 = std::vector<StructState_std::allocator<StructState>>::erase(v2, &result, it);
                                v9 = v8->baseclass_0.baseclass_0.baseclass_0._Mycont;
                                v10 = v8->baseclass_0._Myptr;
                                it.baseclass_0.baseclass_0.baseclass_0._Mycont = v9;
                                it.baseclass_0._Myptr = v10;
                                StructCreature::CalculateStat(v1);
                                v11 = v1->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                *&state.m_szStateValue[16] = &state;
                                (v11[19].ProcDelete)(v1, &state);
                                v15 = -1;
                            }
                            else
                            {
                                std::_Vector_const_iterator<StructState_std::allocator<StructState>>::operator__(&it.baseclass_0);
                            }
                            *&state.m_szStateValue[16] = v2;
                        }
            */

        }
        // Function       :   public void StructCreature::RemoveGoodState(int)
        // Function       :   public void PendClearStateWithFlag(const enum StateInfo::_ATTRIBUTE_FLAG &)
        // Function       :   public const class std::vector<StructState,std::allocator<StructState> > & GetStateList()
        // Function       :   public int GetStateLevel(enum StructState::StateCode, unsigned long)

        public State GetState(State.StateCode code)
        {
            foreach (State s in m_vStateList)
            {
                if (s.m_info.id == (int)code)
                    return s;
            }
            return null;
        }
        // Function       :   public struct StructState * StructCreature::GetStateByUID(unsigned short)

        public bool ClearExpiredState(uint t)
        {
            /*
                        v24 = &state ^ __security_cookie;
                        v2 = this;
                        bRtn = 0;
                        if (t == 0)
                            t = Globals.GetArTime();
                        std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                            &it,
                            v2->m_vStateList._Myfirst,
                            &v2->m_vStateList.baseclass_0.___u0.baseclass_0);
                        v3 = v2->m_vStateList._Mylast;
                        *&state.m_szStateValue[16] = v2 + 1316;
                        for
                        for ( *&state.m_szStateValue[12] = v3; ; *&state.m_szStateValue[12] = v2->m_vStateList._Mylast )
                        {
                            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                                &thisa,
                                *&state.m_szStateValue[12],
                                *&state.m_szStateValue[16]);
                            if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(&it, &thisa) )
                                break;
                            v4 = 0;
                            if ( LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.z) == 4501 )
                            {
                                if ( v2->m_nHavoc < 1 )
                                    v4 = 1;
                            }
                            v5 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                            if ( StructState::ClearExpiredState(v5, ta) )
                            {
                                bRtn = 1;
                                v6 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                if ( !StructState::IsValid(v6, ta) )
                                    goto LABEL_11;
                                v7 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                v8 = v2->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                *&state.m_szStateValue[16] = 0;
                                *&state.m_szStateValue[12] = v7;
                                (v8[19].IsDeleteable)(v2, v7, 0);
                            }
                            if ( !v4 )
                            {
                                std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                std::_Vector_const_iterator<StructState_std::allocator<StructState>>::operator__(&it.baseclass_0);
                                goto LABEL_20;
                            }
                    LABEL_11:
                            if ( LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.z) == 4504 )
                            {
                                StructCreature::AddEnergy(v2);
                            }
                            else
                            {
                                if ( LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.z) == 4501 )
                                {
                                    bRtn = 1;
                                }
                                else
                                {
                                    v9 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                    if ( StructState::GetEffectType(v9) == 83 )
                                    {
                                        if ( v2->baseclass_0.baseclass_0.baseclass_0.vfptr[1].ProcDelete(v2) )
                                            v2[1].baseclass_0.baseclass_0.bIsRegionChanging = 1;
                                    }
                                }
                            }
                            v10 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                            StructState::StructState(&state, v10);
                            v22 = 0;
                            v11 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                            v12 = v2->baseclass_0.baseclass_0.baseclass_0.vfptr;
                            *&state.m_szStateValue[16] = 1;
                            *&state.m_szStateValue[12] = v11;
                            (v12[19].IsDeleteable)(v2, v11, 1);
                            v13 = std::vector<StructState_std::allocator<StructState>>::erase(&v2->m_vStateList, &result, it);
                            v14 = v13->baseclass_0.baseclass_0.baseclass_0._Mycont;
                            v15 = v13->baseclass_0._Myptr;
                            it.baseclass_0.baseclass_0.baseclass_0._Mycont = v14;
                            it.baseclass_0._Myptr = v15;
                            StructCreature::CalculateStat(v2);
                            v16 = v2->baseclass_0.baseclass_0.baseclass_0.vfptr;
                            *&state.m_szStateValue[16] = &state;
                            (v16[19].ProcDelete)(v2, &state);
                            v22 = -1;
                            state.vfptr = &StructState::_vftable_;
                    LABEL_20:
                            *&state.m_szStateValue[16] = v2 + 1316;
                        }
                        return bRtn;
            */
            return false;
        }

        public void RemoveAllAura()
        {

        }

        public void RemoveAllStateByDeadOrLogout()
        {

        }

        public void RemoveAllStateByQuittingHuntaholic()
        {

        }
        // Function       :   public const bool IsFeared()
        // Function       :   public const bool IsHavocBurst()
        // Function       :   public const bool IsFormChanged()
        // Function       :   public bool IsPhysicalImmune()

        public bool IsMagicalImmune()
        {
            if (this.GetState(State.StateCode.Seal) != null || this.GetState(State.StateCode.ShineWall) != null)
                return true;
            return false;
        }

        // Function       :   public bool IsNeedStateNotify()

        public virtual bool IsActable()
        {
            bool result = false;
            if (this.m_nHP != 0)
            {
                if ((this.m_StatusFlag & StatusFlags.Feared) == 0)
                {
                    if ((this.m_StatusFlag & (StatusFlags.Movable | StatusFlags.Attackable | StatusFlags.SkillCastable | StatusFlags.MagicCastable | StatusFlags.ItemUsable)) != 0)
                        result = true;
                }
            }
            return result;
        }

        public virtual bool IsAttackable()
        {
            bool result;

            if (!this.IsActable()
              || this.IsSitDown()
              || this.m_pCastSkill != null)
                result = false;
            else
                result = (this.m_StatusFlag & StatusFlags.Attackable) != 0;
            return result;
        }

        public override bool IsMovable()
        {
            bool result;

            if (this.m_nHP == 0 || this.IsSitDown() || this.m_nMovableTime > Globals.GetArTime() || this.m_pCastSkill != null)
                result = false;
            else
                result = ((this.m_StatusFlag & StatusFlags.Movable) != 0);
            return result;
        }
        // Function       :   public bool IsNeedToUpdateState()
        // Function       :   public void SetNeedToUpdateState(bool)
        // Function       :   public bool StructCreature::IsKnockbackable()

        public virtual bool IsItemUseable()
        {
            bool result;

            if (!this.IsActable() || this.m_pCastSkill != null)
                result = false;
            else
                result = (this.m_StatusFlag & StatusFlags.ItemUsable) != 0;
            return result;
        }

        public virtual bool IsItemWearable()
        {
            return this.IsActable();
        }

        public virtual bool IsSkillCastable()
        {
            bool result;
            if (!this.IsActable()
              || this.GetState(State.StateCode.Mute) != null
              || this.IsSitDown()
              || this.m_pCastSkill != null
              || this.m_hEnemy != 0)
                result = false;
            else
                result = (this.m_StatusFlag & StatusFlags.SkillCastable) != 0;
            return result;
        }

        public virtual bool IsMagicCastable()
        {
            bool result;

            if (!this.IsActable()
              || this.GetState(State.StateCode.Mute) != null
              || this.IsSitDown()
              || this.m_pCastSkill != null
              || this.m_hEnemy != 0)
                result = false;
            else
                result = (this.m_StatusFlag & StatusFlags.MagicCastable) != 0;
            return result;
        }

        public virtual bool IsEnemy(Creature pTarget, bool bIncludeHiding)
        {
            bool result;

            //return true;

            if (pTarget != null && pTarget.bIsInWorld
                //                && (this.m_StatusFlag & StatusFlags.Invincible) == 0
                //              && (this.m_StatusFlag & StatusFlags.Mortal) != 0
                //              && (pTarget.m_StatusFlag & StatusFlags.Invincible) == 0
                //              && (pTarget.m_StatusFlag & StatusFlags.Mortal) != 0
              && (bIncludeHiding || this.IsVisible(pTarget))
              && !this.IsAlly(pTarget))
                result = !pTarget.IsPet();
            else
                result = false;
            return result;
        }

        public virtual bool IsAlly(Creature pTarget)
        {
            return false;
        }

        public bool ResurrectByState()
        {
            return false;
        }

        public bool AddAimer(uint aimer)
        {
            if (this.m_vAimerList.Contains(aimer))
            {
                return false;
            }
            this.m_vAimerList.Add(aimer);
            return true;
        }

        public bool RemoveAimer(uint aimer)
        {
            if (this.m_vAimerList.Contains(aimer))
            {
                this.m_vAimerList.Remove(aimer);
                return true;
            }
            return false;
        }

        public void ReleaseAimerList()
        {
            foreach (uint h in this.m_vAimerList)
            {
                Player p = Player.get(h) as Player;
                if (p != null)
                {
                    p.SetTarget(0);
                }
            }
            this.m_vAimerList.Clear();
        }
        // UserDefinedType:   SKILL_FUNCTOR
        // VTable         :     , Type:  *
        // Function       :     public void onSkill(int, int, int, int, unsigned long, unsigned long)
        // Function       :     public void SKILL_FUNCTOR(const struct StructCreature::SKILL_FUNCTOR &)
        // Function       :     public void SKILL_FUNCTOR()
        // Function       :     public struct StructCreature::SKILL_FUNCTOR & operator=(const struct StructCreature::SKILL_FUNCTOR &)
        // UserDefinedType:   STATE_FUNCTOR
        // VTable         :     , Type:  *
        // Function       :     public void onState(const struct StructState *)
        // Function       :     public void STATE_FUNCTOR(const struct StructCreature::STATE_FUNCTOR &)
        // Function       :     public void STATE_FUNCTOR()
        // Function       :     public struct StructCreature::STATE_FUNCTOR & operator=(const struct StructCreature::STATE_FUNCTOR &)
        // UserDefinedType:   SKILL_POINTER_FUNCTOR
        // VTable         :     , Type:  *
        // Function       :     public void onSkill(struct StructSkill *)
        // Function       :     public void SKILL_POINTER_FUNCTOR(const struct StructCreature::SKILL_POINTER_FUNCTOR &)
        // Function       :     public void SKILL_POINTER_FUNCTOR()
        // Function       :     public struct StructCreature::SKILL_POINTER_FUNCTOR & operator=(const struct StructCreature::SKILL_POINTER_FUNCTOR &)
        // Function       :   public struct StructSkill * GetCastSkill()
        public Skill SetSkill(int skill_uid, int skill_id, int skill_level, uint remain_cool_time)
        {
            Skill result = null; // eax@1

            SkillBase sb = GameContent.GetSkillBase(skill_id);
            if (sb != null)
            {
                Skill cs = this.GetSkill(skill_id);
                if (cs == null)
                {
                    cs = MemoryPool.AllocSkill(this, skill_uid, skill_id);

                    this.m_vAllSkillList.Add(cs);

                    if (cs.m_SkillBase.is_active != 0)
                        this.m_vActiveSkillList.Add(cs);
                    else
                        this.m_vPassiveSkillList.Add(cs);
                }

                cs.m_nSkillLevel = skill_level;
                if (remain_cool_time != 0)
                    cs.SetRemainCoolTime(remain_cool_time);
                result = cs;
            }
            return result;
        }

        public void RegisterSkill(int skill_id, int skill_level, uint remain_cool_time, int nJobId)
        {
            // .text:00437C74 n1              = qword ptr -5Ch
            // .text:00437C74 n2              = qword ptr -54h
            // .text:00437C74 n3              = qword ptr -4Ch
            // .text:00437C74 n4              = qword ptr -44h
            // .text:00437C74 n5              = qword ptr -3Ch
            // .text:00437C74 n7              = qword ptr -34h
            // .text:00437C74 n8              = qword ptr -2Ch
            // .text:00437C74 n9              = qword ptr -24h
            // .text:00437C74 n10             = qword ptr -1Ch
            long nCardUID;              // -20 -14h
            int nPrevLevel;             // -12 -0Ch
            // .text:00437C74 n6              = qword ptr -8
            // .text:00437C74 skill_id        = dword ptr  8
            // .text:00437C74 skill_level     = dword ptr  0Ch
            Skill pSkill;               // 16 10h
            int nSkillUID;              // 20 14h
            int nNeedJP;
            Player player;
            Summon summon;


            nCardUID = 0;
            if (nJobId == 0)
                nJobId = this.GetJobId();
            nNeedJP = (int)GameContent.GetNeedJpForSkillLevelUp(skill_id, skill_level, nJobId);

            if (this.GetJobPoint() >= nNeedJP)
            {
                this.m_nJobPoint -= nNeedJP;
                if (this.m_nJobPoint < 0)
                    this.m_nJobPoint = 0;

                this.onExpChange();

                nSkillUID = 0;
                nPrevLevel = this.GetBaseSkillLevel(skill_id);
                if (nPrevLevel == 0)
                {
                    nSkillUID = Interlocked.Increment(ref s_nMaxSkillUID);
                }
                pSkill = this.SetSkill(nSkillUID, skill_id, skill_level, remain_cool_time);
                if (pSkill != null)
                {
                    if (this.IsPlayer())
                    {
                        player = this as Player;
                        ServerLog.Log((ushort)0x8FE, player.GetAccountID(), player.GetSID(), 0, skill_id, skill_level, nNeedJP, this.m_nJobPoint, nSkillUID,
                            0, 0, nCardUID, player.GetAccountName(), player.GetName(), "", "");
                    }
                    else
                    {
                        if (this.IsSummon())
                        {
                            summon = this as Summon;
                            player = summon.m_master;
                            nCardUID = 0;
                            if (summon.m_item != null)
                                nCardUID = summon.m_item.m_Instance.UID;
                            ServerLog.Log((ushort)0xA2A, player.GetAccountID(), player.GetSID(), summon.GetSID(), skill_id, skill_level, nNeedJP,
                                summon.m_nJobPoint, nSkillUID, 0, 0, nCardUID, player.GetAccountName(), player.GetName(), summon.GetName(), "");
                        }
                    }
                    if (pSkill.m_SkillBase.is_active == 0)
                        this.CalculateStat();
                    this.onRegisterSkill(pSkill.m_nSkillUID, skill_id, nPrevLevel, skill_level);
                }
            }

        }

        // Function       :   public unsigned int GetSkillCount()
        // Function       :   public int StructCreature::GetAllSkillJP()
        // Function       :   public int StructCreature::GetAllJobLevelJP()
        // Function       :   public bool StructCreature::ResetSkill()

        public int GetBaseSkillLevel(int skill_id)
        {
            Skill s = this.GetSkill(skill_id);
            if (s != null)
                return s.m_nSkillLevel;
            return 0;
        }

        public int GetCurrentSkillLevel(int skill_id)
        {
            Skill s = this.GetSkill(skill_id);
            if (s != null)
                return s.m_nSkillLevel + s.m_nSkillLevelAdd;
            return 0;
        }


        public int GetCurrentPassiveSkillLevel(int skill_id)
        {
            Skill s = this.GetCurrentPassiveSkill(skill_id);
            if (s != null)
                return s.m_nSkillLevel + s.m_nSkillLevelAdd;
            else
                return 0;
        }

        public Skill GetCurrentPassiveSkill(int skill_id)
        {
            foreach (Skill s in m_vPassiveSkillList)
            {
                if (s.m_nSkillId == skill_id)
                    return s;
            }
            return null;
        }

        public Skill GetSkill(int nSkillId)
        {
            foreach (Skill s in m_vAllSkillList)
            {
                if (s.m_nSkillId == nSkillId)
                    return s;
            }
            return null;
        }

        // Function       :   public const struct StructSkill * StructCreature::GetSkillByEffectType(const int)

        public uint GetRemainCoolTime(int skill_id)
        {
            uint result = 0;

            uint ct = Globals.GetArTime();

            Skill sk = this.GetSkill(skill_id);
            if (GameRule.bNoSkillCooltime || sk == null || sk.m_nNextCoolTime < ct)
                result = 0;
            else
                result = sk.m_nNextCoolTime - ct;
            return result;

        }

        public uint GetTotalCoolTime(int skill_id)
        {
            uint result = 0;

            Skill sk = this.GetSkill(skill_id);
            if (GameRule.bNoSkillCooltime || sk == null)
                result = 0;
            else
                result = sk.GetSkillCoolTime();
            return result;
        }

        public void EnumSkill(SkillFunctor fn)
        {
            uint t;

            t = Globals.GetArTime();

            foreach (Skill s in this.m_vAllSkillList)
            {
                if (s.m_nSkillUID > 0)
                {
                    fn.onSkill(s.m_nSkillUID, s.m_SkillBase.uid, s.m_nSkillLevel, s.m_nSkillLevel + s.m_nSkillLevelAdd, s.GetSkillCoolTime(),
                        s.m_nNextCoolTime <= t ? 0 : s.m_nNextCoolTime - t);
                }
            }
        }

        public void EnumActiveSkill(SkillPtrFunctor fn)
        {

        }

        public void EnumPassiveSkill(SkillPtrFunctor fn)
        {
            foreach (Skill s in this.m_vPassiveSkillList)
            {
                fn.onSkill(s);
            }

        }
        // Function       :   public void EnumState(struct StructCreature::STATE_FUNCTOR &)

        public bool CancelSkill()
        {
            bool result;

            Skill s = this.m_pCastSkill;
            if (s != null && s.Cancel())
            {
                this.m_pCastSkill = null;
                result = true;
            }
            else
            {
                result = false;
            }
            return result;
        }

        public bool OnCompleteSkill()
        {
            bool result;
            if (this.m_pCastSkill != null)
            {
                this.m_pCastSkill = null;
                result = true;
            }
            else
            {
                result = false;
            }
            return result;
        }

        public int CastSkill(int nSkillId, int nSkillLevel, uint target_handle, ArPosition pos, byte layer, bool bIsCastedByItem)
        {
            // enemyPosition   = ArPosition ptr -114h
            // .text:00434F44 myPosition      = ArPosition ptr -104h
            // .text:00434F44 target_pos      = ArPosition ptr -0F4h
            // .text:00434F44 target_handle   = dword ptr  0Ch
            // .text:00434F44 pos             = dword ptr  10h
            float range_mod;                // 72 48h
            Creature pSkillTarget;          // 76 4Ch
            // .text:00434F44 it              = GameObject::iterator ptr  50h
            float enemy_distance;           // 92 5Ch
            // .text:00434F44 nSkillId        = dword ptr  104 68h
            // .text:00434F44 nSkillLevel     = dword ptr  6Ch
            Player pPlayer = null;          // 112 70h
            Skill pSkill;                   // 116 74h
            // .text:00434F44 layer           = byte ptr  78h
            // .text:00434F44 bIsCastedByItem = byte ptr  7Ch
            // 
            // Data           :   ebp Relative, [00000068], Param, Type: int, nSkillId
            // Data           :   ebp Relative, [0000006C], Param, Type: int, nSkillLevel
            // Data           :   ebp Relative, [00000070], Param, Type: unsigned int, target_handle
            // Data           :   ebp Relative, [00000074], Param, Type: const struct ArPosition &, pos
            // Data           :   ebp Relative, [00000078], Param, Type: unsigned char, layer
            // Data           :   ebp Relative, [0000007C], Param, Type: bool, bIsCastedByItem
            // Data           :   ebp Relative, [FFFFFF0C], Local, Type: struct ArPosition, target_pos
            // Data           :   ebp Relative, [0000004C], Local, Type: struct StructCreature *, pSkillTarget
            // Data           :   ebp Relative, [00000074], Local, Type: struct StructSkill *, pSkill
            // Data           :   ebp Relative, [00000050], Local, Type: struct GameObject::iterator, it
            // Data           :   ebp Relative, [0000005C], Local, Type: unsigned long, t
            // Data           :   ebp Relative, [00000048], Local, Type: float, range_mod
            // Data           :   ebp Relative, [FFFFFEEC], Local, Type: struct ArPosition, enemyPosition
            // Data           :   ebp Relative, [FFFFFEFC], Local, Type: struct ArPosition, myPosition
            // Data           :   ebp Relative, [0000005C], Local, Type: float, enemy_distance
            // Data           :   ebp Relative, [00000040], Local, Type: class std::_Vector_iterator<int,std::allocator<int> >, it
            // Data           :   ebp Relative, [00000070], Local, Type: struct StructPlayer *, pPlayer

            Player player = this as Player;
            Summon summon;
            GameObject obj;
            uint ct = Globals.GetArTime();
            ArPosition tpos = new ArPosition(pos);
            int res;

            res = 0;
            pSkill = this.GetSkill(nSkillId);
            if (this.m_pCastSkill != null || this.IsPlayer() && player.m_bIsUsingStorage || pSkill == null)
                return 5;

            obj = GameObject.get(target_handle);

            pSkillTarget = null;
            if (obj != null)
            {
                if (obj.IsCreature())
                {
                    pSkillTarget = obj as Creature;
                }
            }

            if (pSkill.m_SkillBase.target == (short)SkillBase.TargetType.Master)
            {
                if (!this.IsSummon())
                    return 5;
                summon = this as Summon;
                if (summon.m_master.m_hHandle != pSkillTarget.m_hHandle)
                    return 5;
            }
            else if (pSkill.m_SkillBase.target == (short)SkillBase.TargetType.SelfWithMaster)
            {
                if (!this.IsSummon())
                    return 5;
                summon = this as Summon;
                if (pSkillTarget.m_hHandle != this.m_hHandle && summon.m_master.m_hHandle != pSkillTarget.m_hHandle)
                    return 5;
            }

            if (pSkill.m_SkillBase.target == (short)SkillBase.TargetType.TargetExceptCaster && pSkillTarget.m_hHandle == this.m_hHandle)
                return 5;

            if (pSkillTarget == null)
            {
                if (nSkillId == 6020 && this.IsPlayer() && player.IsInSiegeOrRaidDungeon()) // return feather
                    return 5;
            }
            else
            {
                if (!pSkillTarget.bIsInWorld)
                    return 5;

                float target_distance = (this.GetCurrentPosition(ct).GetDistance(pSkillTarget.GetCurrentPosition(ct)) - this.GetUnitSize() * 0.5f);
                enemy_distance = target_distance - (pSkillTarget.GetUnitSize() * 0.5f);
                range_mod = 1.2f;
                if (pSkillTarget.mv.bIsMoving)
                {
                    if (pSkillTarget.bIsInWorld)
                        range_mod = 1.5f;
                }
                //target_distance = enemy_distance;
                bool inRange = false;
                if (pSkill.m_SkillBase.cast_range == -1)
                {
                    inRange = enemy_distance < this.GetRealAttackRange() * range_mod;
                }
                else
                {
                    target_distance = 12 * pSkill.m_SkillBase.cast_range * range_mod;
                    inRange = enemy_distance < target_distance;
                }
                if (!inRange)
                {
                    return 2;
                }
                if (pSkill.m_SkillBase.is_corpse != 0 && pSkillTarget.m_nHP != 0)
                    return 5;

                if (pSkillTarget.m_hHandle == this.m_hHandle
                  || pSkillTarget.IsSummon()
                  && (pSkillTarget as Summon).m_master.m_hHandle == this.m_hHandle)
                {
                    if (pSkill.m_SkillBase.IsUsable(0) == 0)
                        return 5;
                }
                else
                {
                    if (this.IsAlly(pSkillTarget))
                    {
                        if (pSkill.m_SkillBase.IsUsable(1) == 0)
                            return 5;
                    }
                    else if (this.IsEnemy(pSkillTarget, false))
                    {
                        if (pSkill.m_SkillBase.IsUsable(5) == 0)
                            return 5;
                    }
                    else if (pSkill.m_SkillBase.IsUsable(3) == 0)
                        return 5;

                }

                if (pSkillTarget.IsPlayer() && pSkill.m_SkillBase.tf_avatar == 0
                  || pSkillTarget.IsMonster() && pSkill.m_SkillBase.tf_monster == 0
                  || pSkillTarget.IsSummon() && pSkill.m_SkillBase.tf_summon == 0)
                    return 5;

                tpos = pSkillTarget.GetCurrentPosition(ct);
            }

            if (this.m_vInterruptedSkill.Count > 0)
            {
                foreach (int sid in this.m_vInterruptedSkill)
                {
                    if (sid == nSkillId)
                        return 5;
                }
            }
            this.mv.SetDirection(tpos);
            this.m_pCastSkill = pSkill;
            res = pSkill.Cast(nSkillLevel, target_handle, tpos, layer, bIsCastedByItem);
            if (res != 0)
            {
                this.m_pCastSkill = null;
                return res;
            }

            RappelzServer.Instance.SetObjectPriority(this, SchedulerObject.Priority.Highest);
            if (!this.IsMonster() || (this as Monster).m_pContentInfo.monster_type < 31)
                return 0;

            if (pSkillTarget == null)
            {
                ServerLog.Log((ushort)0xA90, 0, 0, 0, 0, 0, (this as Monster).GetMonsterId(), (long)this.mv.x, (long)this.mv.y, this.m_layer, nSkillId,
                    nSkillLevel, "", "", "", this.GetName());
                return 0;
            }

            if (pSkillTarget.IsPlayer())
            {
                pPlayer = pSkillTarget as Player;
            }
            else
            {
                if (pSkillTarget.IsSummon())
                    pPlayer = (pSkillTarget as Summon).m_master;
            }

            if (pPlayer != null)
            {
                ServerLog.Log((ushort)0xA90, pPlayer.GetAccountID(), pPlayer.GetSID(), (long)pSkillTarget.mv.x, (long)pSkillTarget.mv.y,
                    pSkillTarget.m_layer, (this as Monster).GetMonsterId(), (long)this.mv.x, (long)this.mv.y, this.m_layer, nSkillId, nSkillLevel,
                    pPlayer.GetAccountName(), pPlayer.GetName(), pSkillTarget.GetName(), this.GetName());
            }
            else
            {
                ServerLog.Log((ushort)0xA90, 0, 0, (long)pSkillTarget.mv.x, (long)pSkillTarget.mv.y, pSkillTarget.m_layer, (this as Monster).GetMonsterId(),
                    (long)this.mv.x, (long)this.mv.y, this.m_layer, nSkillId, nSkillLevel, "", "", pSkillTarget.GetName(), this.GetName());
            }

            return 0;
        }

        // Function       :   public void FireSkill()

        public bool IsActiveAura(Skill pSkill)
        {
            return false;
            //             char *v2; // esi@1
            //             unsigned int *v4; // [sp-8h] [bp-1Ch]@1
            //             std::_Container_base *v5; // [sp-4h] [bp-18h]@1
            //             std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > thisa; // [sp+4h] [bp-10h]@1
            //             std::_Vector_iterator<std::pair<StructSkill *,int>,std::allocator<std::pair<StructSkill *,int> > > it; // [sp+Ch] [bp-8h]@1
            // 
            //             v2 = &this->m_vAura;
            //             std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
            //                 &thisa,
            //                 this->m_vAura._Myfirst,
            //                 &this->m_vAura.baseclass_0.___u0.baseclass_0);
            //             it.baseclass_0.baseclass_0.baseclass_0._Mycont = thisa.baseclass_0.baseclass_0._Mycont;
            //             v5 = v2;
            //             v4 = *(v2 + 2);
            //             it.baseclass_0._Myptr = thisa._Myptr;
            //             while ( 1 )
            //             {
            //                 std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
            //                     &thisa,
            //                     v4,
            //                     v5);
            //                 if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(&it, &thisa) )
            //                     return 0;
            //                 if ( LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x) == pSkill )
            //                     break;
            //                 std::_Vector_const_iterator<std::pair<GameContent::HUNTAHOLIC_MONSTER_RESPAWN_INFO_const___unsigned_long>_std::allocator<std::pair<GameContent::HUNTAHOLIC_MONSTER_RESPAWN_INFO_const___unsigned_long>>>::operator__(&it);
            //                 v5 = v2;
            //                 v4 = *(v2 + 2);
            //             }
            //             return 1;

        }
        // Function       :   public bool StructCreature::TurnOnAura(struct StructSkill *)
        // Function       :   public bool StructCreature::TurnOffAura(struct StructSkill *)
        // Function       :   public void StructCreature::ToggleAura(struct StructSkill *)

        public virtual bool IsUsingSkill()
        {
            return m_pCastSkill != null;
        }

        public void BindSkillCard(Item card)
        {
            Skill skill = this.GetSkill(card.m_pItemBase.nSkillID);
            if (skill != null)
            {
                skill.m_nEnhance = card.m_Instance.nEnhance;
                card.SetBindTarget(this);
                Messages.SendSkillCardInfo(card);
            }

        }

        public void UnBindSkillCard(Item pItem)
        {
            Skill s = this.GetSkill(pItem.m_pItemBase.nSkillID);
            if (s != null)
            {
                s.m_nEnhance = 0;
                pItem.SetBindTarget(null);
                Messages.SendSkillCardInfo(pItem);
            }
        }
        // Function       :   public struct StructCreature::StateMod * GetMagicalSkillStatePenalty()
        // Function       :   public void SetTrapHandle(const unsigned int)
        
        public uint GetTrapHandle()
        {
            uint result;

            result = this.m_hTrap;
            if (result != 0)
            {
                GameObject trap = GameObject.raw_get(result);
                if (trap != null
                  && trap.IsSkillProp()
                  && trap.bIsInWorld
                  && !trap.bIsDeleteRequested)
                {
                    result = this.m_hTrap;
                }
                else
                {
                    this.m_hTrap = 0;
                    result = 0;
                }
            }
            return result;

        }

        public ushort onItemUseEffect(Creature pCaster, Item pItem, int type, float var1, float var2, string szParameter)
        {
            // .text:004394B9 foChecker       = StructCreature::onItemUseEffect::__l164::RecallFeatherCheckFunctor ptr -4F4h
            // .text:004394B9 var_4E4         = qword ptr -4E4h
            // .text:004394B9 this            = TS_SC_SHOW_SET_PET_NAME ptr -4DCh
            ArPosition pos = new ArPosition();          //             = ArPosition ptr -4D0h
            // .text:004394B9 fo              = StructCreature::onItemUseEffect::__l168::RecallFeatherFunctor ptr -4C0h
            // .text:004394B9 cnt             = qword ptr -494h
            // .text:004394B9 fIP             = c_fixed<10000> ptr -48Ch
            // .text:004394B9 n8              = qword ptr -47Ch
            // .text:004394B9 n2              = qword ptr -374h
            // .text:004394B9 n6              = qword ptr -364h
            // .text:004394B9 n10             = qword ptr -354h
            // .text:004394B9 elemental_effect_expire_time= qword ptr -294h
            long gold;                                      // -564 -234h
            // .text:004394B9 n1              = qword ptr -214h
            // .text:004394B9 n3              = qword ptr -204h
            // .text:004394B9 n5              = qword ptr -1F4h
            // .text:004394B9 n7              = qword ptr -1E4h
            // .text:004394B9 n9              = qword ptr -1D4h
            // .text:004394B9 n11             = qword ptr -1C4h
            long nItemCount;                            // -364 -16Ch
            // .text:004394B9 elemental_effect_type= dword ptr -164h
            long nIncGold;                              // -352 -160h
            // .text:004394B9 var_158         = dword ptr -158h
            int nItemID;                                // -340 -154h
            // .text:004394B9 nCasterGuildID  = dword ptr -150h
            // .text:004394B9 bUnsummonOnly   = byte ptr -149h
            // .text:004394B9 pit             = StructPlayer::iterator ptr -148h
            // .text:004394B9 nAllianceID     = dword ptr -140h
            Player pPlayer = null;                          // -316 -13Ch
            // .text:004394B9 layer           = dword ptr -138h
            ushort nRet = 0;                                // -308 -134h
            // .text:004394B9 var_130         = dword ptr -130h
            // .text:004394B9 var_128         = dword ptr -128h
            // .text:004394B9 msg             = TS_SC_CHANGE_NAME ptr -124h
            // .text:004394B9 szBuf           = byte ptr -104h
            int prev_hp;                                // -28  -1Ch
            float prev_mp;
            // .text:004394B9 var_4           = dword ptr -4
            // .text:004394B9 pCaster         = dword ptr  8
            Item pCItem = null;                          // 12   0Ch
            // .text:004394B9 type            = dword ptr  10h
            // .text:004394B9 var1            = dword ptr  14h
            // .text:004394B9 var2            = dword ptr  18h
            // .text:004394B9 szParameter     = dword ptr  28   1Ch
            // 
            // Data           :   ebp Relative, [0000012C], Param, Type: struct StructCreature *, pCaster
            // Data           :   ebp Relative, [00000130], Param, Type: struct StructItem *, pItem
            // Data           :   ebp Relative, [00000134], Param, Type: int, type
            // Data           :   ebp Relative, [00000138], Param, Type: float, var1
            // Data           :   ebp Relative, [0000013C], Param, Type: float, var2
            // Data           :   ebp Relative, [00000140], Param, Type: const char *, szParameter

            // Data           :   ebp Relative, [FFFFFFEC], Local, Type: struct StructItem *, pWearingRideItem
            // Data           :   ebp Relative, [FFFFFFEC], Local, Type: struct StructItem *, pNewItem
            // Data           :   ebp Relative, [FFFFFFC4], Local, Type: struct StructGold, nIncGold
            // Data           :   ebp Relative, [00000020], Local, Type: char[0xFF], szBuf
            // Data           :   ebp Relative, [FFFFFC64], Local, Type: struct StructCreature::onItemUseEffect::__l168::RecallFeatherFunctor, fo
            // Data           :   ebp Relative, [FFFFFC30], Local, Type: struct StructCreature::onItemUseEffect::__l164::RecallFeatherCheckFunctor, foChecker
            // Typedef        :   StructCreature::onItemUseEffect::__l164::RecallFeatherCheckFunctor, Type: struct StructCreature::onItemUseEffect::__l164::RecallFeatherCheckFunctor
            // Typedef        :   StructCreature::onItemUseEffect::__l168::RecallFeatherFunctor, Type: struct StructCreature::onItemUseEffect::__l168::RecallFeatherFunctor
            // Data           :   ebp Relative, [00000000], Local, Type: struct TS_SC_CHANGE_NAME, msg
            // Data           :   ebp Relative, [FFFFFFE8], Local, Type: struct StructPlayer *, pPlayer
            // Data           :   ebp Relative, [FFFFFFEC], Local, Type: unsigned char, layer
            // Data           :   ebp Relative, [FFFFFFDC], Local, Type: struct StructPlayer::iterator, pit
            // Data           :   ebp Relative, [FFFFFFD4], Local, Type: int, nCasterGuildID
            // Data           :   ebp Relative, [FFFFFFE4], Local, Type: int, nAllianceID
            // Data           :   ebp Relative, [FFFFFFDB], Local, Type: bool, bUnsummonOnly
            // Data           :   ebp Relative, [FFFFFC48], Local, Type: struct TS_SC_SHOW_SET_PET_NAME, msg
            string szBuf;
            uint target_handle;
            int i;

            pPlayer = pCaster as Player;
            PacketOut pak;
            uint ct = Globals.GetArTime();

            switch (type)
            {
                case 1:
                    prev_hp = this.m_nHP;
                    this.HealByItem((int)var1);
                    Messages.BroadcastHPMPMsg(this, this.m_nHP - prev_hp, 0, false);
                    break;

                case 2:
                    prev_mp = this.m_fMP;
                    this.MPHealByItem(var1);
                    Messages.BroadcastHPMPMsg(this, 0, this.m_fMP - prev_mp, false);
                    break;

                case 5:
                    target_handle = this.m_hHandle;
                    if (6020.0f == var1 || 6021.0f == var1)
                        target_handle = pItem.m_hHandle;
                    pos.z = 0.0f;
                    pos.y = 0.0f;
                    pos.x = 0.0f;
                    pos.face = 0.0f;
                    return (ushort)pCaster.CastSkill((int)var1, (int)var2, target_handle, pos, this.m_layer, true);

                case 6:
                    if (!this.IsPlayer())
                    {
                        this.AddState(State.StateType.Normal, (State.StateCode)pItem.m_pItemBase.nStateCode, pItem.m_Instance.OwnerHandle,
                            pItem.m_pItemBase.nStateLevel, ct, ct + (uint)(100 * pItem.m_pItemBase.nStateTime), false, 0, "");
                        return nRet;
                    }
                    StateInfo state = GameContent.GetStateInfo(pItem.m_pItemBase.nStateCode);
                    if (state == null)
                        return 5;
                    if (state.effect_type != 200 || pPlayer.m_nRideIdx == 0 && pPlayer.m_nRidingStateUid != 0 && !pPlayer.IsInDungeon())
                    {
                        if (pItem.m_pItemBase.nStateCode == 4003)
                        {
                            if (pPlayer.GetState(State.StateCode.StaminaSave) != null)
                                return 37;
                        }
                        this.AddState(State.StateType.Normal, (State.StateCode)pItem.m_pItemBase.nStateCode, pItem.m_Instance.OwnerHandle,
                            pItem.m_pItemBase.nStateLevel, ct, ct + (uint)(100 * pItem.m_pItemBase.nStateTime), false, 0, "");
                        return nRet;
                    }
                    return 6;

                case 7:
                    this.RemoveState((State.StateCode)pItem.m_pItemBase.nStateCode, pItem.m_pItemBase.nStateLevel);
                    break;

                case 8:
                    Item pWornItem = this.GetWornItem(ItemBase.ItemWearType.WearRideItem);
                    if (this.GetState((State.StateCode)pItem.m_pItemBase.nStateCode) != null && pItem.IsSameObject(pWornItem))
                    {
                        this.RemoveState((State.StateCode)pItem.m_pItemBase.nStateCode, pItem.m_pItemBase.nStateLevel);
                        break;
                    }
                    if (pPlayer != null)
                    {
                        if (pPlayer.m_nRideIdx != 0 || pPlayer.m_nRidingStateUid != 0 || pPlayer.IsInDungeon())
                        {
                            if (GameContent.GetStateInfo(pItem.m_pItemBase.nStateCode).effect_type == 200)
                                return 6;
                        }
                        if (pWornItem != null)
                        {
                            if (!pItem.IsSameObject(pWornItem))
                            {
                                if (pPlayer.Putoff(ItemBase.ItemWearType.WearRideItem) != 0)
                                    return 6;
                                if (pPlayer.Puton(ItemBase.ItemWearType.WearRideItem, pItem) != 0)
                                    return 6;
                            }
                        }
                        else
                        {
                            if (pPlayer.Puton(ItemBase.ItemWearType.WearRideItem, pItem) != 0)
                                return 6;
                        }
                        pPlayer.AddState(0, (State.StateCode)pItem.m_pItemBase.nStateCode, pItem.m_Instance.OwnerHandle,
                            pItem.m_pItemBase.nStateLevel, ct, 0xffffffff, true, 0, "");
                    }
                    break;




                case 90:
                    if (pCaster.IsPlayer())
                    {
                        if (pItem.m_pItemBase.nGroup != 18 || (pItem.m_Instance.Flag & 0x20) == 0)
                            return 5;
                        if (pItem.m_pPet == null)
                        {
                            if (pItem.m_pItemBase.nSummonId == 0)
                                return 5;
                            pItem.m_pPet = MemoryPool.AllocNewPet(pPlayer, pItem, pItem.m_pItemBase.nSummonId);
                            if (pItem.m_pPet == null)
                                return 5;
                            pPlayer.AddPet(pItem.m_pPet, true);
                            pItem.m_pPet.DBQuery(new DB_InsertPet(pItem.m_pPet));
                            pItem.DBQuery(new DB_UpdateItem(pItem));
                        }
                        if (pPlayer.bIsInWorld
                              && pPlayer.m_nHP != 0
                              && !pPlayer.m_bIsUsingStorage
                              && pPlayer.m_BoothStatus == Player.BoothStatus.IsNotBooth
                              && pPlayer.m_pBoothOpener == null
                              && pPlayer.m_hTradeTarget == 0
                              && pPlayer.m_pCastSkill == null
                              && pPlayer.m_nRideIdx == 0
                              && pPlayer.m_nRidingStateUid == 0)
                        {
                            if (pItem.m_pPet.m_bNameChanged)
                            {
                                if (pPlayer.m_pSummonedPet == null)
                                {
                                    pPlayer.SummonPet(pItem.m_pPet);
                                }
                                else
                                {
                                    pPlayer.UnSummonPet();
                                    if (pPlayer.m_pSummonedPet.m_hHandle != pItem.m_pPet.m_hHandle)
                                    {
                                        pPlayer.SummonPet(pItem.m_pPet);
                                    }
                                }
                            }
                            else
                            {
                                pak = new PacketOut(ClientOutPackets.ShowPetSetName);
                                pak.WriteUInt32(pItem.m_pPet.m_hHandle);
                                pPlayer.Connection.SendTCP(pak);
                            }
                            return 0;
                        }
                        return 5;
                    }
                    break;

                case 94:
                    if (!pCaster.IsPlayer())
                        return 6;
                    if (var1 != 0.0f)
                    {
                        int total = 1;
                        if (var1 < 0.0f)
                            total = (int)var2;

                        for (i = 0; i < total; ++i)
                        {
                            nItemID = (int)var1;
                            nItemCount = (int)var2;
                            while (nItemID < 0)
                            {
                                GameContent.SelectItemIDFromDropGroup(nItemID, out nItemID, out nItemCount);
                            }
                            if (nItemID != 0)
                            {
                                pCItem = Item.AllocItem(0, nItemID, nItemCount, ItemInstance.GenerateCode.ByItem, -1, -1, -1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0);
                                Item pNewItem = pPlayer.PushItem(pCItem, pCItem.m_Instance.nCount, false);
                                ServerLog.Log((ushort)0x961, pPlayer.GetAccountID(), pPlayer.GetSID(), pCItem.m_Instance.nLevel + 100 * pCItem.m_Instance.nEnhance,
                                    pCItem.m_Instance.Code, pCItem.m_Instance.nCount, pNewItem == null ? 0 : pNewItem.m_Instance.nCount, 0,
                                    0, (long)pPlayer.mv.x, (long)pPlayer.mv.y, pCItem.m_Instance.UID, pPlayer.GetAccountName(), pPlayer.GetName(), "", "IGEN");
                                if (pNewItem != null)
                                    Messages.SendResult(pPlayer, 204, 0, pNewItem.m_hHandle);

                                if (pCItem.IsSameObject(pNewItem))
                                    Item.PendFreeItem(pCItem);
                            }
                            else
                            {
                                ServerLog.Log((ushort)0x961, pPlayer.GetAccountID(), pPlayer.GetSID(), 0, 0, 0, 0, 0,
                                    0, (long)pPlayer.mv.x, (long)pPlayer.mv.y, 0, pPlayer.GetAccountName(), pPlayer.GetName(), "", "IGEN");
                            }
                        }
                        return nRet;
                    }
                    else
                    {
                        gold = pPlayer.m_nGold + (long)var2;
                        if (pPlayer.ChangeGold(gold) != 0)
                            return 53;
                        ServerLog.Log((ushort)2401, pPlayer.GetAccountID(), pPlayer.GetSID(), 0, 0, 0, 0, (long)var2, pPlayer.m_nGold,
                            (long)pPlayer.mv.x, (long)pPlayer.mv.y, 0, pPlayer.GetAccountName(), pPlayer.GetName(), "", "IGEN");
                    }
                    break;

                case 101:
                    prev_hp = this.m_nHP;
                    this.HealByItem((int)(this.m_nMaxHP * var1));
                    Messages.BroadcastHPMPMsg(this, this.m_nHP - prev_hp, 0, false);
                    break;

                case 102:
                    prev_mp = this.m_fMP;
                    this.MPHealByItem((this.m_nMaxMP * var1));
                    Messages.BroadcastHPMPMsg(this, 0, this.m_fMP - prev_mp, false);
                    break;

                case 103:
                    nIncGold = Globals.GetRandomInt32((int)var1, (int)var2);
                    if (pPlayer.ChangeGold(nIncGold + pPlayer.m_nGold) != 0)
                        return 53;

                    ServerLog.Log(2401, pPlayer.GetAccountID(), pPlayer.GetSID(), 0, 0, 0, 0, nIncGold, pPlayer.m_nGold, -1, (long)this.mv.x, (long)this.mv.y,
                        pPlayer.GetAccountName(), pPlayer.GetName(), "", "IGEN");
                    break;



            }

            return nRet;

            // 
            //             v331 = &msg ^ __security_cookie;
            //             v7 = pCastera;
            //             pPlayer = pItema;
            //             layer = szParametera;
            //             v8 = 0;
            //             v9 = this;
            //             Player player = this as Player;
            //             Player player_caster = pCaster as Player;
            //             nRet = 0;
            //             if (type > 94)
            //             {
            //                 if (type <= 113)
            //                 {
            //                     if (type != 113)
            //                     {
            //                         if (type == 103)
            //                         {
            // 
            //                         }
            //                         else
            //                         {
            //                             if (type != 104)
            //                             {
            //                                 if (type != 112)
            //                                     return nRet;
            //                                  // 112
            //                                 if (!this.IsPlayer()
            //                                   || !pCaster.IsPlayer()
            //                                   || player_caster.IsInSiegeOrRaidDungeon() )
            //                                     goto LABEL_236;
            //                                 *&v92 = *(v7 + 28);
            //                                 *&szBuf[236] = *(v7 + 172);
            //                                 *&szBuf[228] = *&v92;
            //                                 *&szBuf[220] = *(v7 + 27);
            //                                 szBuf = String.Format("recall_feather( %f, %f, %d )", *&szBuf[220], v92, v92 >> 32, *&szBuf[236]);
            //                                 if (1.0f != var1)
            //                                 {
            //                                     if ( !*(v7 + 1061) )
            //                                         goto LABEL_236;
            //                                     ::::RecallFeatherCheckFunctor::RecallFeatherCheckFunctor(&foChecker, v7, pPlayer);
            //                                     v100 = *(v7 + 1061);
            //                                     *&szBuf[236] = &foChecker;
            //                                     *&szBuf[232] = v100;
            //                                     v101 = PartyManager::GetInstance();
            //                                     PartyManager::DoEachMember(v101, *&szBuf[232], *&szBuf[236]);
            //                                     if ( !foChecker.m_nResult )
            //                                     {
            //                                         fo.szTrigger = szBuf;
            //                                         fo.m_pCaster = v7;
            //                                         v102 = *(v7 + 1061);
            //                                         *&szBuf[236] = &fo;
            //                                         *&szBuf[232] = v102;
            //                                         fo.baseclass_0.vfptr = &::::RecallFeatherFunctor::_vftable_;
            //                                         v103 = PartyManager::GetInstance();
            //                                         PartyManager::DoEachMember(v103, *&szBuf[232], *&szBuf[236]);
            //                                         return nRet;
            //                                     }
            //                                     v18 = LOWORD(foChecker.m_nResult);
            //         LABEL_37:
            //                                     return v18;
            //                                 }
            //                                 if ( StructPlayer::IsInEventmap(v9) && !StructItem::IsUsableInEventmap(pPlayer) )
            //                                     return 49;
            //                                 if ( !v9->m_nHP
            //                                   || (v93 = *(&v9[1].baseclass_0.m_nRefCount + 1)) == 0
            //                                   || v93 != *(v7 + 1061)
            //                                   || BYTE6(v9[1].m_AttributeAmplifier.fMoveSpeedDecreaseResistance.value)
            //                                   || v7 == v9 )
            //                                     goto LABEL_236;
            //                                 StructPlayer::SetFixedDialogTrigger(v9, szBuf);
            //                                 LOBYTE(v9[1].m_StateStatePenalty.nDamage) = 1;
            //                                 *&szBuf[236] = szBuf;
            //                                 v94 = (*(*v7 + 60))(v7);
            //                                 SendWindowMessage(v9, "recall_feather_confirm_window", v94, *&szBuf[236]);
            //                                 v95 = v9->baseclass_0.baseclass_0.mv.baseclass_0.y;
            //                                 v303 = v9->baseclass_0.baseclass_0.layer;
            //                                 v301 = v95;
            //                                 v299 = v9->baseclass_0.baseclass_0.mv.baseclass_0.x;
            //                                 v297 = (v9->baseclass_0.baseclass_0.baseclass_0.vfptr[3].onProcess)(v9);
            //                                 v96 = StructPlayer::GetAccountID(v9);
            //                                 v97 = *(v7 + 28);
            //                                 v295 = v96;
            //                                 v293 = *(v7 + 172);
            //                                 v291 = v97;
            //                                 v289 = *(v7 + 27);
            //                                 v287 = *(v7 + 1061);
            //                                 v285 = (*(*v7 + 64))(v7);
            //                                 v282 = StructPlayer::GetAccountID(v7);
            //                                 v98 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                                 *&szBuf[236] = -1;
            //                                 *&szBuf[232] = v98[3].GetHandle(v9);
            //                                 *&szBuf[228] = -1;
            //                                 *&szBuf[224] = StructPlayer::GetAccountName(v9);
            //                                 v99 = *v7;
            //                                 *&szBuf[220] = -1;
            //                                 *&szBuf[216] = (*(v99 + 60))(v7);
            //                                 *&szBuf[212] = -1;
            //                                 *&szBuf[208] = StructPlayer::GetAccountName(v7);
            //                                 *&szBuf[204] = &v303;
            //                                 *&szBuf[200] = &v301;
            //                                 *&szBuf[196] = &v299;
            //                                 *&szBuf[192] = &v297;
            //                                 *&szBuf[188] = &v295;
            //                                 *&szBuf[184] = &v293;
            //                                 *&szBuf[180] = &v291;
            //                                 *&szBuf[176] = &v289;
            //                                 *&szBuf[172] = &v287;
            //                                 *&szBuf[168] = &v285;
            //                                 *&szBuf[164] = &v282;
            //                                 *&szBuf[160] = 2418;
            //         LABEL_187:
            //                                 LOG::Log11N4S(
            //                                     *&szBuf[160],
            //                                     *&szBuf[164],
            //                                     *&szBuf[168],
            //                                     *&szBuf[172],
            //                                     *&szBuf[176],
            //                                     *&szBuf[180],
            //                                     *&szBuf[184],
            //                                     *&szBuf[188],
            //                                     *&szBuf[192],
            //                                     *&szBuf[196],
            //                                     *&szBuf[200],
            //                                     *&szBuf[204],
            //                                     *&szBuf[208],
            //                                     *&szBuf[212],
            //                                     *&szBuf[216],
            //                                     *&szBuf[220],
            //                                     *&szBuf[224],
            //                                     *&szBuf[228],
            //                                     *&szBuf[232],
            //                                     *&szBuf[236]);
            //                                 return nRet;
            //                             }
            // 104
            //                             *&szBuf[236] = var2a;
            //                             *&szBuf[232] = var1a;
            //                             v104 = XFastRandom(*&szBuf[232], *&szBuf[236]);
            //                             v105 = StructPlayer::GetHuntaholicPoint(v9);
            //                             StructPlayer::SetHuntaholicPoint(v9, v104 + v105);
            //                             v106 = v9->baseclass_0.baseclass_0.mv.baseclass_0.y;
            //                             v278 = 0;
            //                             v279 = 0;
            //                             v107 = v106;
            //                             v108 = v9->baseclass_0.baseclass_0.mv.baseclass_0.x;
            //                             v275 = v107;
            //                             v273 = v108;
            //                             v266 = 0;
            //                             v267 = 0;
            //                             v264 = StructPlayer::GetHuntaholicPoint(v9);
            //                             v261 = v104;
            //                             v109 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                             v257 = 806808;
            //                             v258 = 0;
            //                             v254 = 0;
            //                             v255 = 0;
            //                             v251 = (v109[3].onProcess)(v9);
            //                             v110 = StructPlayer::GetAccountID(v9);
            //                             *&szBuf[236] = -1;
            //                             v249 = v110;
            //                             v111 = *&v9[1].baseclass_0.baseclass_0.mv.ends.baseclass_0.___u0.baseclass_0.dummy[0];
            //                             *&szBuf[232] = "IGEN";
            //                             v270 = v111;
            //                             v112 = v9[1].baseclass_0.baseclass_0.mv.ends._Myfirst;
            //                             *&szBuf[228] = 0;
            //                             *&szBuf[224] = &unk_5F42BB;
            //                             v271 = v112;
            //                             v113 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                             *&szBuf[220] = -1;
            //                             *&szBuf[216] = v113[3].GetHandle(v9);
            //                             *&szBuf[212] = -1;
            //                             *&szBuf[208] = StructPlayer::GetAccountName(v9);
            //                             *&szBuf[204] = &v278;
            //                             *&szBuf[200] = &v275;
            //                             *&szBuf[196] = &v273;
            //                             *&szBuf[192] = &v270;
            //                             *&szBuf[188] = &v266;
            //                             *&szBuf[184] = &v264;
            //                             *&szBuf[180] = &v261;
            //                             *&szBuf[176] = &v257;
            //                             *&szBuf[172] = &v254;
            //                             *&szBuf[168] = &v251;
            //                             v70 = &v249;
            //                         }
            //         LABEL_186:
            //                         *&szBuf[164] = v70;
            //                         *&szBuf[160] = 2401;
            //         LABEL_187:
            //                                 LOG::Log11N4S(
            //                                     *&szBuf[160],
            //                                     *&szBuf[164],
            //                                     *&szBuf[168],
            //                                     *&szBuf[172],
            //                                     *&szBuf[176],
            //                                     *&szBuf[180],
            //                                     *&szBuf[184],
            //                                     *&szBuf[188],
            //                                     *&szBuf[192],
            //                                     *&szBuf[196],
            //                                     *&szBuf[200],
            //                                     *&szBuf[204],
            //                                     *&szBuf[208],
            //                                     *&szBuf[212],
            //                                     *&szBuf[216],
            //                                     *&szBuf[220],
            //                                     *&szBuf[224],
            //                                     *&szBuf[228],
            //                                     *&szBuf[232],
            //                                     *&szBuf[236]);
            //                                 return nRet;
            //                     }
            // 113
            //                     if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
            //                       || (LODWORD(nCasterGuildID) = v9->baseclass_0.baseclass_0.baseclass_0.vfptr[5].ProcDelete(v9),
            //                           var1a > SLODWORD(nCasterGuildID)) )
            //                         goto LABEL_236;
            //                     goto LABEL_192;
            //                 }
            //                 if ( typea == 115 )
            //                 {
            //                     if ( (this->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)() )
            //                     {
            //                         if ( StructSummon::GetRidingInfo(v9) != 1 )
            //                         {
            //                             v136 = v9->baseclass_0.baseclass_0.bIsInWorld;
            //                             v137 = v9[1].baseclass_0.baseclass_0.prev_ry;
            //                             pPlayer = v9[1].baseclass_0.baseclass_0.prev_ry;
            //                             if ( v136 )
            //                             {
            //                                 if ( v137 )
            //                                 {
            //                                     if ( v137 == v7 )
            //                                     {
            //                                         if ( *(v137 + 68) )
            //                                         {
            //                                             v138 = *(v137 + 5280);
            //                                             if ( !v138 || !*(v138 + 68) )
            //                                             {
            //                                                 if ( layer == 0.0 )
            //                                                     goto LABEL_257;
            //                                                 strlen(LODWORD(layer));
            //                                                 if ( v139 < 4 )
            //                                                     goto LABEL_257;
            //                                                 v140 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr[3].GetHandle(v9);
            //                                                 strlen(v140);
            //                                                 v141 = LODWORD(layer);
            //                                                 nAllianceID = v142;
            //                                                 strlen(LODWORD(layer));
            //                                                 v144 = v143 < nAllianceID;
            //                                                 v319 = v143;
            //                                                 v145 = &nAllianceID;
            //                                                 if ( !v144 )
            //                                                     v145 = &v319;
            //                                                 *&szBuf[236] = *v145;
            //                                                 v146 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr[3].GetHandle(v9);
            //                                                 if ( strncmp(v141, v146, *&szBuf[236])
            //                                                   && (*&szBuf[236] = 18,
            //                                                       *&szBuf[232] = 4,
            //                                                       strlen(v141),
            //                                                       GameRule::IsValidName(v141, v147 + 1, *&szBuf[232], *&szBuf[236]))
            //                                                   && !GameContent::IsBannedWord(v141) )
            //                                                 {
            //                                                     v148 = *&v9[1].baseclass_0.baseclass_0.bIsRegionChanging;
            //                                                     v213 = *(v148 + 200);
            //                                                     v214 = *(v148 + 204);
            //                                                     v149 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                                                     v209 = 0;
            //                                                     v210 = 0;
            //                                                     v206 = 0;
            //                                                     v207 = 0;
            //                                                     v203 = 0;
            //                                                     v204 = 0;
            //                                                     v199 = 0;
            //                                                     v200 = 0;
            //                                                     v196 = 0;
            //                                                     v197 = 0;
            //                                                     v193 = 0;
            //                                                     v194 = 0;
            //                                                     v189 = 0;
            //                                                     v190 = 0;
            //                                                     v150 = (v149[3].onProcess)(v9);
            //                                                     v151 = pPlayer;
            //                                                     v186 = v150;
            //                                                     v183 = *(pPlayer + 1052);
            //                                                     v152 = StructPlayer::GetAccountID(pPlayer);
            //                                                     *&szBuf[236] = -1;
            //                                                     *&szBuf[232] = LODWORD(layer);
            //                                                     v180 = v152;
            //                                                     v153 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                                                     *&szBuf[228] = -1;
            //                                                     *&szBuf[224] = v153[3].GetHandle(v9);
            //                                                     v154 = *v151;
            //                                                     *&szBuf[220] = -1;
            //                                                     *&szBuf[216] = (*(v154 + 60))(v151);
            //                                                     *&szBuf[212] = -1;
            //                                                     v155 = StructPlayer::GetAccountName(v151);
            //                                                     LOG::Log11N4S(
            //                                                         0xA2Eu,
            //                                                         &v180,
            //                                                         &v183,
            //                                                         &v186,
            //                                                         &v189,
            //                                                         &v193,
            //                                                         &v196,
            //                                                         &v199,
            //                                                         &v203,
            //                                                         &v206,
            //                                                         &v209,
            //                                                         &v213,
            //                                                         v155,
            //                                                         *&szBuf[212],
            //                                                         *&szBuf[216],
            //                                                         *&szBuf[220],
            //                                                         *&szBuf[224],
            //                                                         *&szBuf[228],
            //                                                         *&szBuf[232],
            //                                                         *&szBuf[236]);
            //                                                     StructSummon::SetName(v9, LODWORD(layer));
            //                                                     *&szBuf[236] = v9->baseclass_0.baseclass_0.baseclass_0.vfptr[3].GetHandle(v9);
            //                                                     v156 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                                                     *&szBuf[232] = "name";
            //                                                     v157 = v156->GetHandle(v9);
            //                                                     SendPropertyMessage(v151, v157, *&szBuf[232], *&szBuf[236]);
            //                                                     TS_SC_CHANGE_NAME::TS_SC_CHANGE_NAME(&msg);
            //                                                     msg.handle = v9->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v9);
            //                                                     strncpy(msg.name, LODWORD(layer), 0x12u);
            //                                                     v158 = v9->baseclass_0.baseclass_0.layer;
            //                                                     *&nAllianceID = g_nRegionSize;
            //                                                     msg.name[18] = 0;
            //                                                     v159 = v9->baseclass_0.baseclass_0.mv.baseclass_0.y;
            //                                                     LOBYTE(v319) = v158;
            //                                                     v160 = (v159 / *&nAllianceID);
            //                                                     v161 = v9->baseclass_0.baseclass_0.mv.baseclass_0.x / *&nAllianceID;
            //                                                     *&szBuf[236] = &msg;
            //                                                     *&szBuf[228] = __PAIR__(v319, v160);
            //                                                     *&szBuf[224] = v161;
            //                                                     v162 = ArcadiaServer::Instance();
            //                                                     ArcadiaServer::Broadcast(
            //                                                         v162,
            //                                                         *&szBuf[224],
            //                                                         *&szBuf[228],
            //                                                         szBuf[232],
            //                                                         *&szBuf[236]);
            //                                                     v9->m_StatusFlag.m_flag[0] |= 0x80u;
            //                                                 }
            //                                                 else
            //                                                 {
            //         LABEL_257:
            //                                                     nRet = 19;
            //                                                 }
            //                                                 return nRet;
            //                                             }
            //                                         }
            //                                     }
            //                                 }
            //                             }
            //                         }
            //                     }
            //                     goto LABEL_236;
            //                 }
            //                 if ( typea == 116 )
            //                 {
            //                     if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)()
            //                       || !v9->baseclass_0.baseclass_0.bIsInWorld
            //                       || !v9->m_nHP
            //                       || v9[1].baseclass_0.baseclass_0.prev_ry != v7 )
            //                         goto LABEL_236;
            //         LABEL_192:
            //                     v122 = StructCreature::ResetSkill(v9);
            //         LABEL_193:
            //                     LOWORD(v18) = v18 != 0 ? 0 : 6;
            //         LABEL_36:
            //                     v18 = v18;
            //                     goto LABEL_37;
            //                 }
            //                 if ( typea != 117 )
            //                 {
            //                     if ( typea != 118 )
            //                     {
            //                         if ( typea != 119 )
            //                             return nRet;
            //                         if ( (*(*pCastera + 24))(pCastera) )
            //                         {
            //                             if ( 0.0 != var1a )
            //                                 v8 = 1;
            //                             v123 = (**pPlayer)();
            //                             if ( !StructPlayer::ChangeName(v7, LODWORD(layer), v8, 1, v123) )
            //                                 nRet = 7;
            //                             return nRet;
            //                         }
            //                         goto LABEL_236;
            //                     }
            //                     if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
            //                       || (LODWORD(nCasterGuildID) = v9->baseclass_0.baseclass_0.baseclass_0.vfptr[5].ProcDelete(v9),
            //                           var1a > SLODWORD(nCasterGuildID)) )
            //                         goto LABEL_236;
            //                     v122 = StructPlayer::ResetJob(v9, 0);
            //                     goto LABEL_193;
            //                 }
            //                 if ( !(*(*pCastera + 24))(pCastera) )
            //                     goto LABEL_236;
            //                 if ( layer == 0.0 )
            //                     return 28;
            //                 v124 = StructPlayer::FindPlayer(LODWORD(layer));
            //                 StructPlayer::get(&pit, v124);
            //                 v328 = 0;
            //                 if ( HIDWORD(pit)
            //                   && *(HIDWORD(pit) + 68)
            //                   && *(HIDWORD(pit) + 4109)
            //                   && *(HIDWORD(pit) + 1028) & 1
            //                   && HIDWORD(pit) != v9 )
            //                 {
            //                     v125 = HIDWORD(pit);
            //                     if ( StructPlayer::IsInSecroute(HIDWORD(pit)) )
            //                     {
            //                         nRet = 48;
            //         LABEL_231:
            //                         LODWORD(pit) = &StructPlayer::iterator::_vftable_;
            //                         GameObject::iterator::_iterator(&pit);
            //                         return nRet;
            //                     }
            //                     if ( StructPlayer::IsInSiegeOrRaidDungeon(v125) )
            //                     {
            //                         nRet = 47;
            //                         goto LABEL_231;
            //                     }
            //                     if ( StructPlayer::IsInEventmap(v125) )
            //                     {
            //                         nRet = 49;
            //                         goto LABEL_231;
            //                     }
            //                     *&szBuf[236] = v125 + 108;
            //                     LODWORD(nItemID) = v125 + 108;
            //                     v126 = HuntaholicManager::Instance();
            //                     if ( HuntaholicManager::GetHuntaholicID(v126, *&szBuf[236]) )
            //                     {
            //                         nRet = 57;
            //                         goto LABEL_231;
            //                     }
            //                     v127 = *(&v125[23].baseclass_0.baseclass_0.bIsDeleteRequested + 1);
            //                     if ( v127 && v127 == *(v7 + 1061)
            //                       || (v128 = v125[23].baseclass_0.baseclass_0.last_proc_tick,
            //                           v129 = *(v7 + 1064),
            //                           LODWORD(nCasterGuildID) = *(v7 + 1064),
            //                           v128)
            //                       && v128 == v129
            //                       || (*&szBuf[236] = v128,
            //                           v130 = GuildManager::GetInstance(),
            //                           nAllianceID = GuildManager::GetAllianceID(v130, *&szBuf[236]),
            //                           *&nAllianceID != 0.0)
            //                       && (*&szBuf[236] = LODWORD(nCasterGuildID),
            //                           v131 = GuildManager::GetInstance(),
            //                           v132 = GuildManager::GetAllianceID(v131, *&szBuf[236]),
            //                           nAllianceID == v132) )
            //                     {
            //                         v133 = v125->baseclass_0.mv.baseclass_0.y;
            //                         *&szBuf[236] = v125->baseclass_0.layer;
            //                         *&szBuf[232] = v133;
            //                         StructPlayer::PendWarp(v7, *LODWORD(nItemID), v133, szBuf[236]);
            //                         *&szBuf[236] = 5;
            //                         *&szBuf[232] = v7;
            //                         v134 = ArcadiaServer::Instance();
            //                         ArcadiaServer::SetObjectPriority(v134, *&szBuf[232], *&szBuf[236]);
            //                         goto LABEL_231;
            //                     }
            //                 }
            //                 nRet = 6;
            //                 goto LABEL_231;
            //             }
            //             if ( typea > 8 )
            //             {
            //                 if ( typea == 41 )
            //                 {
            //                     if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
            //                       || c_fixed<10000>::operator<_<enum__StructState::_unnamed_tag_>(
            //                              (&v9[1].m_ResistAmplifier.fResist[0] + 6),
            //                              0) )
            //                         goto LABEL_236;
            //                     v290 = *(&v9[1].m_ResistAmplifier.fResist[0].value + 6) / 10000.0 + var1a;
            //                     v164 = 0.0;
            //                     v61 = &v290;
            //                     if ( v290 <= 0.0 )
            //                         v61 = &v164;
            //                     v226 = (10000.0 * *v61);
            //                     v60 = &v226;
            //                 }
            //                 else
            //                 {
            //                     if ( typea != 42 )
            //                     {
            //                         if ( typea != 43 )
            //                         {
            //                             if ( typea == 80 )
            //                             {
            //                                 if ( (this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
            //                                 {
            //                                     *&szBuf[236] = var1a;
            //                                     StructPlayer::AddStamina(v9, *&szBuf[236]);
            //                                     return nRet;
            //                                 }
            //                             }
            //                             else
            //                             {
            //                                 if ( typea != 90 )
            //                                     return nRet;
            // TYPE 90
            //                                 if ( (*(*pCastera + 24))(pCastera) )
            //                                 {
            //                                     v42 = *(pPlayer + 83);
            //                                     v43 = *(pPlayer + 85);
            //                                     if ( *(v42 + 12) != 18 || !(*(pPlayer + 288) & 0x20) )
            //                                         return 5;
            //                                     if ( !v43 )
            //                                     {
            //                                         v44 = *(v42 + 104);
            //                                         if ( !v44 || (v45 = AllocNewPet(v7, pPlayer, v44), (v43 = v45) == 0) )
            //                                             return 5;
            //                                         StructPlayer::AddPet(v7, v45, 1);
            //                                         v46 = GameDBManager::DBProc::operator new(0x188u);
            //                                         v319 = v46;
            //                                         v328 = 1;
            //                                         if ( v46 )
            //                                             DB_InsertPet::DB_InsertPet(v46, v43);
            //                                         else
            //                                             v47 = 0;
            //                                         StructPet::DBQuery(v43, v47);
            //                                         v48 = GameDBManager::DBProc::operator new(0x164u);
            //                                         v319 = v48;
            //                                         v328 = 2;
            //                                         if ( v48 )
            //                                             DB_UpdateItem::DB_UpdateItem(v48, pPlayer);
            //                                         else
            //                                             v49 = 0;
            //                                         v328 = -1;
            //                                         StructItem::DBQuery(pPlayer, v49);
            //                                     }
            //                                     if ( *(v7 + 68)
            //                                       && *(v7 + 53)
            //                                       && !*(v7 + 4992)
            //                                       && !*(v7 + 1121)
            //                                       && !*(v7 + 1137)
            //                                       && !*(v7 + 1152)
            //                                       && !*(v7 + 989)
            //                                       && !*(v7 + 1376)
            //                                       && !*(v7 + 1375) )
            //                                     {
            //                                         if ( v43->m_bNameChanged )
            //                                         {
            //                                             v50 = *(v7 + 1354);
            //                                             if ( !v50 )
            //                                                 goto LABEL_258;
            //                                             v51 = v50 == *(pPlayer + 85);
            //                                             bUnsummonOnly = 0;
            //                                             if ( v51 )
            //                                                 bUnsummonOnly = 1;
            //                                             StructPlayer::UnSummonPet(v7);
            //                                             if ( !bUnsummonOnly )
            //                                             {
            //         LABEL_258:
            //                                                 *&szBuf[236] = *(pPlayer + 85);
            //                                                 StructPlayer::SummonPet(v7, *&szBuf[236]);
            //                                             }
            //                                         }
            //                                         else
            //                                         {
            //                                             TS_SC_SHOW_SET_PET_NAME::TS_SC_SHOW_SET_PET_NAME(&thisa);
            //                                             thisa.handle = v43->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v43);
            //                                             PendMessage(v7, &thisa.baseclass_0);
            //                                         }
            //                                         return nRet;
            //                                     }
            //         LABEL_15:
            //                                     return 5;
            //                                 }
            //                             }
            //                             goto LABEL_236;
            //                         }
            //                         if ( !(*(*pCastera + 24))(pCastera) )
            //                             goto LABEL_236;
            //                         v53 = *(v7 + 28);
            //                         *&szBuf[236] = v52;
            //                         *&nAllianceID = v53;
            //                         *&szBuf[232] = v52;
            //                         v54 = *(v7 + 27);
            //                         LOBYTE(layer) = 0;
            //                         nItemID = v54;
            //                         v55 = ChannelManager::GetChannelId(nItemID, *&nAllianceID);
            //                         v56 = ChannelManager::GetChannelId(var1a, var2a);
            //                         if ( v55 && v55 == v56 )
            //                         {
            //                             v57 = *(v7 + 172);
            //                         }
            //                         else
            //                         {
            //                             if ( !v56 )
            //                             {
            //         LABEL_122:
            //                                 *&szBuf[232] = var2a;
            //                                 *&szBuf[228] = var1a;
            //                                 StructPlayer::PendWarp(v7, *&szBuf[228], *&szBuf[232], SLOBYTE(layer));
            //                                 *&szBuf[236] = 5;
            //                                 *&szBuf[232] = v7;
            //                                 v58 = ArcadiaServer::Instance();
            //                                 ArcadiaServer::SetObjectPriority(v58, *&szBuf[232], *&szBuf[236]);
            //                                 return nRet;
            //                             }
            //                             v57 = ChannelManager::GetProperLayer(var1a, var2a);
            //                         }
            //                         LOBYTE(layer) = v57;
            //                         goto LABEL_122;
            //                     }
            //                     if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
            //                       || c_fixed<10000>::operator<_<float>((&v9[1].m_ResistAmplifier.fResist[0] + 6), var1a) )
            //                         goto LABEL_236;
            //                     nCasterGuildID = 0.0;
            //                     v59 = &var1a;
            //                     if ( var1a <= 0.0 )
            //                         v59 = &nCasterGuildID;
            //                     fIP.value = (*v59 * 10000.0);
            //                     v60 = &fIP;
            //                 }
            //                 StructPlayer::SetImmoralPoint(v9, v60);
            //                 BroadcastStatusMessage(v9);
            //                 return nRet;
            //             }
            //             if ( typea == 4 )
            //             {
            //                 nAllianceID = *(pPlayer + 48);
            //                 v19 = this->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                 nRet = 6;
            //                 if ( nAllianceID == (v19->GetHandle)() || v9->m_nHP || (v20 = *v7, *&szBuf[236] = v9, !(*(v20 + 272))(v7, v9)) )
            //                     return nRet;
            //                 v21 = v9->m_nMaxHP;
            //                 nAllianceID = v9->m_nHP;
            //                 StructCreature::AddHP(v9, (v21 * 0.2000000029802322));
            //                 BroadcastHPMPMsg(v9, v9->m_nHP - nAllianceID, 0, 0);
            //                 if ( (v9->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(v9) )
            //                 {
            //                     v22 = (*(*v7 + 24))(v7) != 0 ? v7 : 0;
            //                     if ( v9->m_StatusFlag.m_flag[0] & 0x4000000 )
            //                         v9->m_StatusFlag.m_flag[0] &= 0xFBFFFFFFu;
            //                     if ( v22 )
            //                         LODWORD(layer) = (*(*v22 + 60))(v22);
            //                     else
            //                         LODWORD(layer) = &unk_5F42BB;
            //                     if ( v22 )
            //                         pPlayer = StructPlayer::GetAccountName(v22);
            //                     else
            //                         pPlayer = &unk_5F42BB;
            //                     v23 = v9->baseclass_0.baseclass_0.mv.baseclass_0.y;
            //                     v252 = LODWORD(v9->m_nEXP);
            //                     v253 = HIDWORD(v9->m_nEXP);
            //                     v24 = v9->baseclass_0.baseclass_0.layer;
            //                     v168 = 0;
            //                     v169 = 0;
            //                     v177 = v24;
            //                     v312 = v23;
            //                     v240 = v9->baseclass_0.baseclass_0.mv.baseclass_0.x;
            //                     v308 = 0;
            //                     v309 = 0;
            //                     if ( v22 )
            //                         v25 = *(v22 + 4208);
            //                     else
            //                         v25 = 0;
            //                     v179 = v25;
            //                     if ( v22 )
            //                         v26 = StructPlayer::GetAccountID(v22);
            //                     else
            //                         v26 = 0;
            //                     v306 = v26;
            //                     v27 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                     v237 = 5;
            //                     v238 = 0;
            //                     v304 = (v27[3].onProcess)(v9);
            //                     v28 = StructPlayer::GetAccountID(v9);
            //                     *&szBuf[236] = -1;
            //                     *&szBuf[232] = LODWORD(layer);
            //                     *&szBuf[228] = -1;
            //                     *&szBuf[224] = pPlayer;
            //                     v198 = v28;
            //                     v29 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                     *&szBuf[220] = -1;
            //                     *&szBuf[216] = v29[3].GetHandle(v9);
            //                     *&szBuf[212] = -1;
            //                     *&szBuf[208] = StructPlayer::GetAccountName(v9);
            //                     *&szBuf[204] = &v252;
            //                     *&szBuf[200] = &v168;
            //                     *&szBuf[196] = &v177;
            //                     *&szBuf[192] = &v312;
            //                     *&szBuf[188] = &v240;
            //                     *&szBuf[184] = &v308;
            //                     *&szBuf[180] = &v179;
            //                     *&szBuf[176] = &v306;
            //                     *&szBuf[172] = &v237;
            //                     *&szBuf[168] = &v304;
            //                     *&szBuf[164] = &v198;
            //                     *&szBuf[160] = 2309;
            //                 }
            //                 else
            //                 {
            //                     if ( !v9->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle(v9) )
            //         LABEL_60:
            //                         return 0;
            //                     v30 = v9[1].baseclass_0.baseclass_0.prev_ry;
            //                     n11 = v9->m_nEXP;
            //                     v31 = v9->baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                     n10 = 0i64;
            //                     n9 = 0i64;
            //                     n8 = 0i64;
            //                     n7 = 0i64;
            //                     n6 = 0i64;
            //                     n5 = 0i64;
            //                     n4 = 0i64;
            //                     n3 = (v31[3].onProcess)(v9);
            //                     n2 = (v30->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[3].onProcess)(v30);
            //                     v32 = StructPlayer::GetAccountID(v30);
            //                     *&szBuf[236] = -1;
            //                     n1 = v32;
            //                     *&szBuf[232] = &unk_5F42BB;
            //                     *&szBuf[228] = -1;
            //                     *&szBuf[224] = &unk_5F42BB;
            //                     v33 = v30->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr;
            //                     *&szBuf[220] = -1;
            //                     *&szBuf[216] = v33[3].GetHandle(v30);
            //                     *&szBuf[212] = -1;
            //                     *&szBuf[208] = StructPlayer::GetAccountName(v30);
            //                     *&szBuf[204] = &n11;
            //                     *&szBuf[200] = &n10;
            //                     *&szBuf[196] = &n9;
            //                     *&szBuf[192] = &n8;
            //                     *&szBuf[188] = &n7;
            //                     *&szBuf[184] = &n6;
            //                     *&szBuf[180] = &n5;
            //                     *&szBuf[176] = &n4;
            //                     *&szBuf[172] = &n3;
            //                     *&szBuf[168] = &n2;
            //                     *&szBuf[164] = &n1;
            //                     *&szBuf[160] = 2605;
            //                 }
            //                 LOG::Log11N4S(
            //                     *&szBuf[160],
            //                     *&szBuf[164],
            //                     *&szBuf[168],
            //                     *&szBuf[172],
            //                     *&szBuf[176],
            //                     *&szBuf[180],
            //                     *&szBuf[184],
            //                     *&szBuf[188],
            //                     *&szBuf[192],
            //                     *&szBuf[196],
            //                     *&szBuf[200],
            //                     *&szBuf[204],
            //                     *&szBuf[208],
            //                     *&szBuf[212],
            //                     *&szBuf[216],
            //                     *&szBuf[220],
            //                     *&szBuf[224],
            //                     *&szBuf[228],
            //                     *&szBuf[232],
            //                     *&szBuf[236]);
            //                 goto LABEL_60;
            //             }
            //             if ( typea == 5 )
            //             {
            //                 v16 = (this->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle)();
            //                 if ( 6020.0 == var1a || 6021.0 == var1a )
            //                     v16 = (**pPlayer)();
            //                 v17 = v9->baseclass_0.baseclass_0.layer;
            //                 pos.z = 0.0;
            //                 LOBYTE(nAllianceID) = v17;
            //                 pos.y = 0.0;
            //                 pos.x = 0.0;
            //                 pos.face = 0.0;
            //                 *&szBuf[220] = var2a;
            //                 *&szBuf[216] = var1a;
            //                 LOWORD(v18) = StructCreature::CastSkill(v7, *&szBuf[216], *&szBuf[220], v16, &pos, v17, 1);
            //                 goto LABEL_36;
            //             }
            //             if ( typea == 6 )
            //             {
            //                 v11 = pPlayer;
            //                 if ( !(this->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
            //                 {
            //         LABEL_30:
            //                     v13 = GetArTime();
            //                     v14 = *(pPlayer + 83);
            //                     v15 = 100 * *(v14 + 336);
            //                     *&szBuf[236] = &unk_5F42BB;
            //                     *&szBuf[232] = 0;
            //                     *&szBuf[228] = 0;
            //                     *&szBuf[224] = v13 + v15;
            //         LABEL_31:
            //                     *&szBuf[220] = v13;
            //                     *&szBuf[216] = *(v14 + 332);
            //                     *&szBuf[212] = *(v11 + 48);
            //                     *&szBuf[208] = *(v14 + 328);
            //                     StructCreature::AddState(
            //                         v9,
            //                         0,
            //                         *&szBuf[208],
            //                         *&szBuf[212],
            //                         *&szBuf[216],
            //                         v13,
            //                         *&szBuf[224],
            //                         szBuf[228],
            //                         *&szBuf[232],
            //                         *&szBuf[236]);
            //                     return nRet;
            //                 }
            //                 *&szBuf[236] = *(*(pPlayer + 83) + 328);
            //                 v12 = GameContent::GetStateInfo(*&szBuf[236]);
            //                 if ( !v12 )
            //                     return 5;
            //                 if ( v12->effect_type != 200
            //                   || !LODWORD(v9[1].m_Expert[2].fAvoid) && !LODWORD(v9[1].m_Expert[1].fDamage) && !StructPlayer::IsInDungeon(v9) )
            //                 {
            //                     if ( *(*(pPlayer + 83) + 328) == 4003 )
            //                     {
            //                         if ( StructPlayer::GetPCBangMode(v9) == 2 && !GameRule::bApplyStaminaBonusInPremiumPCBang )
            //                             goto LABEL_259;
            //                         if ( StructPlayer::IsGameTimeLimited(v9) )
            //                         {
            //                             if ( StructPlayer::GetContinuousPlayTime(v9) >= GameRule::nMaxTiredGameTime )
            //                                 return 42;
            //                             if ( StructPlayer::GetContinuousPlayTime(v9) >= GameRule::nMaxHealthyGameTime )
            //                                 return 41;
            //                         }
            //                         if ( StructCreature::GetState(v9, STAMINA_SAVE) )
            //         LABEL_259:
            //                             return 37;
            //                     }
            //                     goto LABEL_30;
            //                 }
            //         LABEL_236:
            //                 return 6;
            //             }
            //             if ( typea == 7 )
            //             {
            //                 v10 = *(pPlayer + 83);
            //                 *&szBuf[236] = *(v10 + 332);
            //                 *&szBuf[232] = *(v10 + 328);
            //         LABEL_12:
            //                 StructCreature::RemoveState(this, *&szBuf[232], *&szBuf[236]);
            //             }
            //             return nRet;
        }

        // Function       :   public void StructCreature::onRegionChange(unsigned int, unsigned int, unsigned int, unsigned int)

        public virtual void onRemoveFromWorld()
        {
            this.RemoveAllHate();
            this.ReleaseAimerList();
        }

        public virtual void onHPChange(int nPrevHP)
        {
            if (nPrevHP == 0)
            {
                if (this.m_nHP > 0)
                {
                    nPrevHP = 128;
                    this.removeStateWithFlag(128);
                }
            }
        }

        public bool IsLoginComplete()
        {
            return (this.m_StatusFlag & StatusFlags.LoginComplete) != 0;
        }

        public void SetLoginComplete()
        {
            this.m_StatusFlag |= StatusFlags.LoginComplete;
        }
        // Function       :   public const bool IsNeedToBroadcastStatusFlag()
        // Function       :   public void SetNeedToBroadcastStatusFlag(const bool)
        // Function       :   public bool HasPendingMove()
        // Function       :   public void ReleasePendingMove()
        // Function       :   public void ProcessAttack()

        public void ProcessAddHPMPOnCritical()
        {

        }
        // Function       :   public void SetNeedCalculateStat()

        public void RemoveExhaustiveSkillStateMod(bool bPhysical, bool bHarmful, int nElementalType, uint nOriginalCastingDelay)
        {
            ElementalSkillStateMod ssmod = null;


            if (bPhysical)
            {
                if (bHarmful)
                    ssmod = this.m_BadPhysicalElementalSkillStateMod[nElementalType];
                else
                    ssmod = this.m_GoodPhysicalElementalSkillStateMod[nElementalType];
            }
            else
            {
                if (bHarmful)
                    ssmod = this.m_BadMagicalElementalSkillStateMod[nElementalType];
                else
                    ssmod = this.m_GoodMagicalElementalSkillStateMod[nElementalType];
            }
            //            this.removeExhaustiveSkillStateMod(ssmod, nOriginalCastingDelay);
            this.CalculateStat();
        }

        // Function       :   public void StructCreature::PrepareRemoveExhaustiveSkillStateMod(bool, bool, int, unsigned long)
        // Function       :   public void SetInvisible(bool)
        // Function       :   public bool IsInvisible()
        // Function       :   public void SetInvincible(bool)
        // Function       :   public bool IsInvincible()
        // Function       :   public bool IsHiding()

        public bool IsVisible(Creature pTarget)
        {
            uint ct = Globals.GetArTime();
            ArPosition pos = this.GetCurrentPosition(ct);

            return (pTarget.m_StatusFlag & StatusFlags.Invisible) == 0
                && ((pTarget.m_StatusFlag & StatusFlags.Hiding) == 0 || this.m_fDetectHideRange > pTarget.GetCurrentPosition(ct).GetDistance(pos));

        }
        // Function       :   public bool IsProcessingReflectDamage()

        public int damage(Creature pFrom, int nDamage, bool decreaseEXPOnDead)
        {
            int result;

            if (this.m_nHP != 0)
            {
                if ((this.m_StatusFlag & StatusFlags.Hiding) != 0)
                    this.RemoveState(State.StateCode.Hide, 65535);

                if (this.m_nHP <= nDamage)
                    this.m_nHP = 0;
                else
                    this.m_nHP -= nDamage;

                if (this.m_nHP == 0)
                {
                    this.m_nDeadTime = Globals.GetArTime();
                    this.onDead(pFrom, decreaseEXPOnDead);
                }
                result = nDamage;
            }
            else
            {
                result = 0;
            }
            return result;
        }
        // Function       :   public int GetHavoc()
        // Function       :   public void SetMaxHavoc(int)
        // Function       :   public int GetMaxHavoc()

        public void SetHavoc(int havoc)
        {
            if (havoc <= this.m_nMaxHavoc)
            {
                if (havoc < 0)
                    havoc = 0;
            }
            else
            {
                havoc = this.m_nMaxHavoc;
            }
            if (this.m_nHavoc != havoc)
            {
                this.m_nHavoc = havoc;
                this.onHavocChange();
            }
        }
        // Function       :   public void AddHavoc(int)
        // Function       :   protected void StructCreature::~StructCreature()

        protected void removeStateByDead()
        {

        }

        protected virtual void removeStateWithFlag(int nFlag)
        {
            /*
                        for(int i = this.m_vStateList.Count-1; i >= 0; --i)
                        {
                            State s = this.m_vStateList[i];

                            if ((s.GetTimeType() & (uint)nFlag) != 0)
                            {
                                v7 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&it);
                                StructState::StructState(&state, (StructState *)v7);
                                v17 = 0;
                                v8 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&it);
                                v9 = v2->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                *(_DWORD *)&state.m_szStateValue[16] = 1;
                                *(_DWORD *)&state.m_szStateValue[12] = v8;
                                ((void (__thiscall *)(StructCreature *, ArMoveVector::MOVE_INFO *, signed int))v9[19].IsDeleteable)(
                                    v2,
                                    v8,
                                    1);
                                v10 = std::vector<StructState_std::allocator<StructState>>::erase(
                                          (std::vector<StructState,std::allocator<StructState> > *)v3,
                                          &result,
                                          it);
                                v11 = v10->baseclass_0.baseclass_0.baseclass_0._Mycont;
                                v12 = v10->baseclass_0._Myptr;
                                it.baseclass_0.baseclass_0.baseclass_0._Mycont = v11;
                                it.baseclass_0._Myptr = v12;
                                StructCreature::CalculateStat(v2);
                                v13 = v2->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                *(_DWORD *)&state.m_szStateValue[16] = &state;
                                ((void (__thiscall *)(StructCreature *, StructState *))v13[19].ProcDelete)(v2, &state);
                                v17 = -1;
                                state.vfptr = (StructStateVtbl *)&StructState::_vftable_;
                            }

                        }
                        v2 = this;
                        v3 = (char *)&this->m_vStateList;
                        std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                            (std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > *)&it,
                            (unsigned int *)this->m_vStateList._Myfirst,
                            &this->m_vStateList.baseclass_0.___u0.baseclass_0);
                        v4 = *((_DWORD *)v3 + 2);
                        *(_DWORD *)&state.m_szStateValue[16] = v3;
                        for ( *(_DWORD *)&state.m_szStateValue[12] = v4; ; *(_DWORD *)&state.m_szStateValue[12] = *((_DWORD *)v3 + 2) )
                        {
                            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                                &thisa,
                                *(unsigned int **)&state.m_szStateValue[12],
                                *(std::_Container_base **)&state.m_szStateValue[16]);
                            if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                                     (std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > *)&it,
                                     (std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > *)&thisa) )
                                break;
                            v5 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&it);
                            else
                            {
                                std::_Vector_const_iterator<StructState_std::allocator<StructState>>::operator__(&it.baseclass_0);
                            }
                            *(_DWORD *)&state.m_szStateValue[16] = v3;
                        }

            */
        }

        protected void processSkill()
        {
            //             StructCreature *v1; // esi@1
            //             ArObject *v2; // ST04_4@1
            //             ArcadiaServer *v3; // eax@1
            //             ArcadiaLock *v4; // eax@1
            //             StructSkill *v5; // esi@1
            //             ArcadiaAutoLock _lock; // [sp+4h] [bp-18h]@1
            //             ArcadiaLock result; // [sp+18h] [bp-4h]@1
            // 
            //             v1 = this;
            //             v2 = this;
            //             v3 = ArcadiaServer::Instance();
            //             v4 = ArcadiaServer::_LockObjectWithVisibleRange(
            //                      v3,
            //                      &result,
            //                      v2,
            //                      "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Struct\\StructCreature.cpp",
            //                      6263);
            //             ArcadiaAutoLock::ArcadiaAutoLock(
            //                 &_lock,
            //                 v4,
            //                 "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Struct\\StructCreature.cpp",
            //                 6263);
            //             v5 = v1->m_pCastSkill;
            //             ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
            if (this.m_pCastSkill != null)
                this.m_pCastSkill.ProcSkill();

        }

        protected void processAttack()
        {
            //             StructCreature *v1; // esi@1
            //             signed __int64 v2; // qax@6
            //             GameObject *v3; // edi@8
            //             int v4; // ebx@9
            //             double v5; // st6@9
            //             unsigned __int64 v6; // qax@9
            //             double v7; // st6@9
            //             double v8; // st7@9
            //             ArcadiaServer *v9; // eax@9
            //             double v10; // st7@10
            //             ArcadiaServer *v11; // eax@16
            //             double v12; // st6@16
            //             unsigned __int64 v13; // qax@16
            //             double v14; // st6@16
            //             double v15; // st7@16
            //             ArcadiaServer *v16; // eax@16
            //             ArSchedulerObjectVtbl *v17; // eax@19
            //             double v18; // st6@21
            //             unsigned __int64 v19; // qax@21
            //             double v20; // st6@21
            //             double v21; // st7@21
            //             bool v22; // zf@25
            //             ArSchedulerObjectVtbl *v23; // eax@25
            //             double v24; // st7@27
            //             volatile bool v25; // al@28
            //             double v26; // st7@29
            //             StructCreature::_ATTACK_INFO *v27; // ebx@31
            //             unsigned int v28; // ebx@33
            //             ArSchedulerObjectVtbl *v29; // ebx@34
            //             int v30; // eax@38
            //             ArSchedulerObjectVtbl *v31; // eax@39
            //             unsigned int v32; // eax@47
            //             int v33; // eax@48
            //             signed int v34; // ecx@49
            //             char *v35; // eax@54
            //             int v36; // ecx@54
            //             int v37; // eax@56
            //             int v38; // eax@58
            //             ArSchedulerObjectVtbl *v39; // eax@60
            //             int v40; // edi@60
            //             ArcadiaAutoLock _lock; // [sp+20h] [bp-58h]@8
            //             __int64 count; // [sp+34h] [bp-44h]@27
            //             double v45; // [sp+3Ch] [bp-3Ch]@27
            //             ArcadiaLock result; // [sp+40h] [bp-38h]@16
            //             ArcadiaLock __lock; // [sp+44h] [bp-34h]@9
            //             int rx1; // [sp+48h] [bp-30h]@9
            //             int ry1; // [sp+4Ch] [bp-2Ch]@9
            //             unsigned int ry2; // [sp+50h] [bp-28h]@9
            //             int rx2; // [sp+60h] [bp-18h]@9

            float attack_range;
            float real_distance;
            ArPosition myPosition;
            ArPosition enemyPosition;
            bool bIsUsingBow;
            bool bIsUsingCrossBow;
            uint t;
            int i;
            Player player;
            uint attInt;
            bool bFormChanged;
            Creature.AttackInfo[] Damages = new Creature.AttackInfo[4];

            t = Globals.GetArTime();
            if (this.IsAttackable())
            {
                bIsUsingBow = this.IsUsingBow();
                bIsUsingCrossBow = this.IsUsingCrossBow();
                if (this.GetNextAttackableTime() <= t)
                {
                    if (bIsUsingBow || bIsUsingCrossBow)
                    {
                        if (this.IsPlayer())
                        {
                            long bullets = this.GetBulletCount();
                            if (bullets < 1)
                            {
                                this.EndAttack();
                                return;
                            }
                        }
                    }
                    //                    *&Damages[3].mp_damage = this.m_hEnemy;
                    Creature enemy = Creature.get(this.m_hEnemy) as Creature;
                    //                     v57 = 0;
                    //                     AutoLock al = new AutoLock();
                    //                     v3 = it.baseclass_0.m_pObject;
                    //                     LOBYTE(v57) = 1;
                    //                     if (enemy == null)
                    //                         goto LABEL_66;
                    //                     v4 = this.mv;
                    //                     attack_range = GameContent.g_nRegionSize;
                    //                     v5 = this.mv.y;
                    //                     rx1 = (this.mv.x / GameContent.g_nRegionSize);
                    //                     v6 = (this.mv.y / GameContent.g_nRegionSize);
                    //                     v7 = enemy.mv.x;
                    //                     ry1 = (this.mv.y / GameContent.g_nRegionSize);
                    //                     v8 = (enemy.mv.y / GameContent.g_nRegionSize);
                    //                     rx2 = (enemy.mv.x / GameContent.g_nRegionSize);
                    //                     *&Damages[3].mp_damage = 6325;
                    //                     *&Damages[3].baseclass_0.elemental_damage[6] = "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Struct\\StructCreature.cpp";
                    //                     *&Damages[3].baseclass_0.elemental_damage[4] = (enemy.mv.y / GameContent.g_nRegionSize);
                    //                     *&Damages[3].baseclass_0.elemental_damage[2] = (enemy.mv.x / GameContent.g_nRegionSize);
                    //                     ry2 = (enemy.mv.y / GameContent.g_nRegionSize);
                    //                     *&Damages[3].baseclass_0.elemental_damage[0] = (this.mv.y / GameContent.g_nRegionSize);
                    //                     Damages[3].baseclass_0.baseclass_0.target_hp = (this.mv.x / GameContent.g_nRegionSize);
                    //                     *&Damages[3].baseclass_0.baseclass_0.bCritical = &__lock;
                    //                     
                    //                     RLock rl1 = RappelzServer.Instance._LockArea((uint)(this.mv.x / GameContent.g_nRegionSize),
                    //                         (uint)(this.mv.y / GameContent.g_nRegionSize),
                    //                         (uint)(enemy.mv.x / GameContent.g_nRegionSize),
                    //                         (uint)(enemy.mv.y / GameContent.g_nRegionSize));
                    //                     while ( 1 )
                    //                     {
                    //                         attack_range = GameContent.g_nRegionSize;
                    //                         v10 = GameContent.g_nRegionSize;
                    //                         if ( rx1 == (this.mv.x / GameContent.g_nRegionSize) )
                    //                         {
                    //                             if ( ry1 == (v1->baseclass_0.baseclass_0.mv.baseclass_0.y / v10)
                    //                               && rx2 == (v3->baseclass_0.mv.baseclass_0.x / v10)
                    //                               && ry2 == (v3->baseclass_0.mv.baseclass_0.y / v10) )
                    //                                 break;
                    //                         }
                    //                         *&Damages[3].mp_damage = &__lock;
                    //                         v11 = ArcadiaServer::Instance();
                    //                         ArcadiaServer::UnLock(v11, *&Damages[3].mp_damage);
                    //                         attack_range = g_nRegionSize;
                    //                         v12 = v1->baseclass_0.baseclass_0.mv.baseclass_0.y;
                    //                         rx1 = (*v4 / attack_range);
                    //                         v13 = (v12 / attack_range);
                    //                         v14 = v3->baseclass_0.mv.baseclass_0.x;
                    //                         ry1 = v13;
                    //                         v15 = v3->baseclass_0.mv.baseclass_0.y / attack_range;
                    //                         rx2 = (v14 / attack_range);
                    //                         *&Damages[3].mp_damage = 6337;
                    //                         *&Damages[3].baseclass_0.elemental_damage[6] = "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Struct\\StructCreature.cpp";
                    //                         *&Damages[3].baseclass_0.elemental_damage[4] = v15;
                    //                         *&Damages[3].baseclass_0.elemental_damage[2] = (v14 / attack_range);
                    //                         ry2 = v15;
                    //                         *&Damages[3].baseclass_0.elemental_damage[0] = v13;
                    //                         Damages[3].baseclass_0.baseclass_0.target_hp = rx1;
                    //                         *&Damages[3].baseclass_0.baseclass_0.bCritical = &result;
                    //                         v16 = ArcadiaServer::Instance();
                    //                         __lock.handle = ArcadiaServer::_LockArea(
                    //                                             v16,
                    //                                             *&Damages[3].baseclass_0.baseclass_0.bCritical,
                    //                                             Damages[3].baseclass_0.baseclass_0.target_hp,
                    //                                             *&Damages[3].baseclass_0.elemental_damage[0],
                    //                                             *&Damages[3].baseclass_0.elemental_damage[2],
                    //                                             *&Damages[3].baseclass_0.elemental_damage[4],
                    //                                             *&Damages[3].baseclass_0.elemental_damage[6],
                    //                                             *&Damages[3].mp_damage)->handle;
                    //                     }
                    //                     ArcadiaAutoLock::set(
                    //                         &_lock,
                    //                         &__lock,
                    //                         "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Struct\\StructCreature.cpp",
                    //                         6340);
                    if (this.m_nHP == 0)
                    {
                        this.CancelAttack();
                    LABEL_63:
                        //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                        return;
                    }
                    if (this.mv.IsMoving(t) || this.m_hEnemy == 0)
                    {
                        //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                        return;
                    }

                    if (enemy == null || !this.IsEnemy(enemy, false) || enemy.m_nHP == 0 || GameContent.IsVisibleRegion((uint)(this.mv.x / GameContent.g_nRegionSize), (uint)(this.mv.y / GameContent.g_nRegionSize), (uint)(enemy.mv.x / GameContent.g_nRegionSize), (uint)(enemy.mv.y / GameContent.g_nRegionSize)) == 0)
                    {
                        player = null;
                        if (this.IsPlayer())
                        {
                            player = this as Player;
                        }
                        else if (this.IsSummon())
                        {
                            Summon summon = this as Summon;
                            player = summon.m_master;
                        }

                        if (player != null)
                            Messages.SendCantAttackMsg(player, player.m_hHandle, player.m_hEnemy, 1);

                        this.EndAttack();
                        //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                        return;
                    }

                    if ((this.m_StatusFlag & StatusFlags.FirsAttack) != 0)
                    {
                        enemy.OnUpdate();
                        this.m_StatusFlag &= ~StatusFlags.FirsAttack;
                    }

                    if (enemy.m_nHP == 0)
                    {
                    LABEL_66:
                        player = null;
                        if (this.IsPlayer())
                        {
                            player = this as Player;
                        }
                        else if (this.IsSummon())
                        {
                            Summon summon = this as Summon;
                            player = summon.m_master;
                        }

                        if (player != null)
                            Messages.SendCantAttackMsg(player, player.m_hHandle, player.m_hEnemy, 1);

                        this.EndAttack();
                        //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                        return;
                    }

                    enemyPosition = enemy.GetCurrentPosition(t);
                    myPosition = this.GetCurrentPosition(t);

                    real_distance = myPosition.GetDistance(enemyPosition) - ((enemy.GetUnitSize() * 0.5f) + (this.GetUnitSize() * 0.5f));
                    attack_range = this.GetRealAttackRange();
                    this.mv.SetDirection(enemyPosition);
                    if (enemy.mv.bIsMoving && enemy.bIsInWorld)
                        attack_range *= 1.5f;
                    else
                        attack_range *= 1.200000047683716f;

                    for (i = 0; i < 4; ++i)
                    {
                        Damages[i] = new Creature.AttackInfo();
                    }

                    bool _bDoubleAttack = false;

                    uint attack_interval = this.GetAttackInterval();
                    attInt = this.GetAttackInterval();
                    int next_mode = this.m_nNextAttackMode;
                    if (attack_range < real_distance)
                    {
                        this.onCantAttack(enemy.m_hHandle, t);
                        //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                        return;
                    }
                    if ((bIsUsingBow || bIsUsingCrossBow) && this.IsPlayer())
                    {
                        if (this.m_nNextAttackMode == 1)
                        {
                            attInt = (uint)(this.GetBowAttackInterval() * 0.800000011920929f);
                            this.SetNextAttackableTime(attInt + t);
                            this.m_nNextAttackMode = 0;
                        LABEL_48:
                            this.m_StatusFlag |= StatusFlags.AttackStarted;

                            bFormChanged = (this.m_StatusFlag & StatusFlags.FormChanged) != 0;

                            if (bFormChanged)
                            {
                                int attack_count = 1;
                                if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                                    attack_count = 2;
                                if (_bDoubleAttack)
                                    attack_count *= 2;
                                if (attack_count > 1)
                                {
                                    i = attack_count - 1;
                                    do
                                    {
                                        Damages[0].nDamage += Damages[i].nDamage;
                                        Damages[0].mp_damage += Damages[i].mp_damage;
                                        Damages[0].attacker_damage += Damages[i].attacker_damage;
                                        Damages[0].attacker_mp_damage += Damages[i].attacker_mp_damage;
                                        Damages[0].target_hp = Damages[i].target_hp;
                                        Damages[0].target_mp = Damages[i].target_mp;
                                        Damages[0].attacker_hp = Damages[i].attacker_hp;
                                        Damages[0].attacker_mp = Damages[i].attacker_mp;
                                        Damages[0].bPerfectBlock |= Damages[i].bPerfectBlock;
                                        Damages[0].bBlock |= Damages[i].bBlock;
                                        Damages[0].bMiss &= Damages[i].bMiss;
                                        Damages[0].bCritical |= Damages[i].bCritical;
                                        Damages[0].elemental_damage[0] += Damages[i].elemental_damage[0];
                                        Damages[0].elemental_damage[1] += Damages[i].elemental_damage[1];
                                        Damages[0].elemental_damage[2] += Damages[i].elemental_damage[2];
                                        Damages[0].elemental_damage[3] += Damages[i].elemental_damage[3];
                                        Damages[0].elemental_damage[4] += Damages[i].elemental_damage[4];
                                        Damages[0].elemental_damage[5] += Damages[i].elemental_damage[5];
                                        Damages[0].elemental_damage[6] += Damages[i].elemental_damage[6];
                                        --i;
                                    }
                                    while (i != 0);
                                }
                            }

                            if (!bFormChanged || next_mode != 1)
                            {
                                int delay = (int)(10 * (this.GetNextAttackableTime() - t));
                                this.broadcastAttackMessage(enemy, Damages, (int)(10 * attInt), delay, _bDoubleAttack, next_mode == 1, false, false);
                            }
                            //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                            return;
                        }

                        attInt = (uint)(this.GetBowAttackInterval() * 0.199999988079071f);
                        attack_interval = attInt + this.GetBowInterval();
                        this.m_nNextAttackMode = 1;
                    }
                    else
                    {
                        next_mode = 0;
                    }
                    if (next_mode == 0)
                    {
                        if ((bIsUsingBow || bIsUsingCrossBow) && this.IsPlayer())
                        {
                            player = this as Player;
                            player.EraseBullet(1);
                        }
                        this.m_nMovableTime = attInt + t;
                        this.Attack(enemy, t, attack_interval, Damages, ref _bDoubleAttack);
                    }
                    this.m_StatusFlag |= StatusFlags.AttackStarted;

                    bFormChanged = (this.m_StatusFlag & StatusFlags.FormChanged) != 0;

                    if (bFormChanged)
                    {
                        int attack_count = 1;
                        if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                            attack_count = 2;
                        if (_bDoubleAttack)
                            attack_count *= 2;
                        if (attack_count > 1)
                        {
                            i = attack_count - 1;
                            do
                            {
                                Damages[0].nDamage += Damages[i].nDamage;
                                Damages[0].mp_damage += Damages[i].mp_damage;
                                Damages[0].attacker_damage += Damages[i].attacker_damage;
                                Damages[0].attacker_mp_damage += Damages[i].attacker_mp_damage;
                                Damages[0].target_hp = Damages[i].target_hp;
                                Damages[0].target_mp = Damages[i].target_mp;
                                Damages[0].attacker_hp = Damages[i].attacker_hp;
                                Damages[0].attacker_mp = Damages[i].attacker_mp;
                                Damages[0].bPerfectBlock |= Damages[i].bPerfectBlock;
                                Damages[0].bBlock |= Damages[i].bBlock;
                                Damages[0].bMiss &= Damages[i].bMiss;
                                Damages[0].bCritical |= Damages[i].bCritical;
                                Damages[0].elemental_damage[0] += Damages[i].elemental_damage[0];
                                Damages[0].elemental_damage[1] += Damages[i].elemental_damage[1];
                                Damages[0].elemental_damage[2] += Damages[i].elemental_damage[2];
                                Damages[0].elemental_damage[3] += Damages[i].elemental_damage[3];
                                Damages[0].elemental_damage[4] += Damages[i].elemental_damage[4];
                                Damages[0].elemental_damage[5] += Damages[i].elemental_damage[5];
                                Damages[0].elemental_damage[6] += Damages[i].elemental_damage[6];
                                --i;
                            }
                            while (i != 0);
                        }
                    }

                    if (!bFormChanged || next_mode != 1)
                    {
                        int delay = (int)(10 * (this.GetNextAttackableTime() - t));
                        this.broadcastAttackMessage(enemy, Damages, (int)(10 * attInt), delay, _bDoubleAttack, next_mode == 1, false, false);
                    }
                    //                        ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                    return;

                }
            }

        }

        protected void processPendingMove()
        {
            uint ct = Globals.GetArTime();
            ArPosition pos;//             = ArPosition ptr -10h


            if ((this.m_StatusFlag & StatusFlags.MovePending) != 0)
            {
                if (this.m_nMovableTime < ct)
                {
                    this.m_StatusFlag &= ~StatusFlags.MovePending;
                    if (this.IsActable() && this.IsMovable())
                    {
                        pos = this.GetCurrentPosition(ct);
                        RappelzServer.Instance.SetMultipleMove(this,pos,this.m_PendingMovePos,(sbyte)this.m_nPendingMoveSpeed,true,ct,true);
                        if (this.IsPlayer())
                        {
                            Player p = this as Player;
                            if (p.m_nRideIdx != 0)
                            {
                                Summon ro = p.GetRideObject();
                                RappelzServer.Instance.SetMultipleMove(ro, pos, this.m_PendingMovePos, (sbyte)this.m_nPendingMoveSpeed, true, ct, true);
                            }
                        }
                        if (this.IsSummon())
                        {
                            RappelzServer.Instance.SetObjectPriority(this, Priority.Normal);
                        }
                    }
                }
            }

        }

        protected virtual void applyState(State state)
        {
// .text:0042EE7D fDamage         = dword ptr -64h
// .text:0042EE7D nApplySkillType = dword ptr -5Ch
// .text:0042EE7D fHate           = dword ptr -54h
// .text:0042EE7D fMagicDamage    = dword ptr -4Ch
// .text:0042EE7D fCoolTime       = qword ptr -48h
// .text:0042EE7D var_40          = dword ptr -40h
// .text:0042EE7D var_3C          = byte ptr -3Ch
// .text:0042EE7D nApplyToHarmful = dword ptr -30h
// .text:0042EE7D fValue2         = dword ptr -2Ch
// .text:0042EE7D var_28          = qword ptr -28h
// .text:0042EE7D var_20          = byte ptr -20h
// .text:0042EE7D var_1C          = dword ptr -1Ch
// .text:0042EE7D var_18          = dword ptr -18h
// .text:0042EE7D _Val            = ArMoveVector::MOVE_INFO ptr -14h
// .text:0042EE7D fValue1         = dword ptr  8
// .text:0042EE7D
// .text:0042EE7D this = ecx
            int effectType = state.GetEffectType();

            switch(effectType)
            {
                case 0:
                    switch (state.m_nCode)
                    {
                        case State.StateCode.Sleep:
                        case State.StateCode.Stun:
                            this.m_StatusFlag &= ~(StatusFlags.Movable|StatusFlags.MagicCastable|StatusFlags.ItemUsable);

                            break;


                    }


/*
.text:0042F640                 mov     this, esi       ; this
.text:0042F642                 call    state.GetLevel()
.text:0042F647                 mov     this, esi       ; this
.text:0042F649                 push    eax             ; n // state.GetLevel()
.text:0042F64A                 lea     eax, [ebp+74h+var_238]
.text:0042F650                 push    eax             ; result
.text:0042F651                 push    1               ; idx
.text:0042F653                 lea     eax, [ebp+74h+var_9B8]
.text:0042F659                 push    eax             ; result
.text:0042F65A                 call    state.GetValue(1)
.text:0042F65F                 mov     this, eax       ; this
.text:0042F661                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort) // (state.GetLevel() * state.GetValue(1))
.text:0042F666                 mov     ebx, eax
.text:0042F668                 push    0               ; idx
.text:0042F66A                 lea     eax, [ebp+74h+var_248]
.text:0042F670                 push    eax             ; result
.text:0042F671                 mov     this, esi       ; this
.text:0042F673                 call    state.GetValue(0)
.text:0042F678                 mov     this, [eax]
.text:0042F67A                 add     this, [ebx] // state.GetValue(0) + (state.GetLevel() * state.GetValue(1))
.text:0042F67C                 mov     eax, [eax+4]
.text:0042F67F                 adc     eax, [ebx+4]
.text:0042F682                 mov     [ebp+74h+_Val.end.face], this // state.GetValue(0) + (state.GetLevel() * state.GetValue(1))
.text:0042F685                 mov     [ebp+74h+_Val.end_time], eax // state.GetValue(0) + (state.GetLevel() * state.GetValue(1))
.text:0042F688                 fild    qword ptr [ebp+74h+_Val.end.face] // state.GetValue(0) + (state.GetLevel() * state.GetValue(1))
.text:0042F68B                 mov     this, esi       ; this
.text:0042F68D                 fdiv    ds:__real@40c3880000000000 // 10000, can be ignored for us since we aren't stupid like gala
.text:0042F693                 fstp    [ebp+74h+fValue1] // state.GetValue(0) + (state.GetLevel() * state.GetValue(1))
.text:0042F696                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void) // state.GetLevel()
.text:0042F69B                 mov     this, esi       ; this
.text:0042F69D                 push    eax             ; n
.text:0042F69E                 lea     eax, [ebp+74h+var_D78]
.text:0042F6A4                 push    eax             ; result
.text:0042F6A5                 push    3               ; idx
.text:0042F6A7                 lea     eax, [ebp+74h+var_258]
.text:0042F6AD                 push    eax             ; result
.text:0042F6AE                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int) // state.GetValue(3)
.text:0042F6B3                 mov     this, eax       ; this
.text:0042F6B5                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort) // (state.GetLevel() * state.GetValue(3))
.text:0042F6BA                 mov     ebx, eax
.text:0042F6BC                 push    2               ; idx
.text:0042F6BE                 lea     eax, [ebp+74h+var_9C8]
.text:0042F6C4                 push    eax             ; result
.text:0042F6C5                 mov     this, esi       ; this
.text:0042F6C7                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int) // state.GetValue(2)
.text:0042F6CC                 mov     this, [ebx]
.text:0042F6CE                 add     this, [eax] // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6D0                 mov     edx, [ebx+4]
.text:0042F6D3                 adc     edx, [eax+4] // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6D6                 mov     [ebp+74h+_Val.end.face], this // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6D9                 mov     [ebp+74h+_Val.end_time], edx // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6DC                 fild    qword ptr [ebp+74h+_Val.end.face] // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6DF                 mov     this, esi       ; this
.text:0042F6E1                 fdiv    ds:__real@40c3880000000000
.text:0042F6E7                 fstp    [ebp+74h+fValue2] // state.GetValue(2) + (state.GetLevel() * state.GetValue(3))
.text:0042F6EA                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
.text:0042F6EF                 mov     this, esi       ; this
.text:0042F6F1                 push    eax             ; n
.text:0042F6F2                 lea     eax, [ebp+74h+var_268]
.text:0042F6F8                 push    eax             ; result
.text:0042F6F9                 push    5               ; idx
.text:0042F6FB                 lea     eax, [ebp+74h+var_F58]
.text:0042F701                 push    eax             ; result
.text:0042F702                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int) // state.GetValue(5)
.text:0042F707                 mov     this, eax       ; this
.text:0042F709                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort) // (state.GetLevel() * state.GetValue(5))
.text:0042F70E                 mov     ebx, eax
.text:0042F710                 push    4               ; idx
.text:0042F712                 lea     eax, [ebp+74h+var_278]
.text:0042F718                 push    eax             ; result
.text:0042F719                 mov     this, esi       ; this
.text:0042F71B                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)// state.GetValue(4)
.text:0042F720                 mov     this, [eax]
.text:0042F722                 add     this, [ebx] // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F724                 mov     eax, [eax+4] // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F727                 adc     eax, [ebx+4] // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F72A                 mov     [ebp+74h+_Val.end.face], this // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F72D                 mov     [ebp+74h+_Val.end_time], eax // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F730                 fild    qword ptr [ebp+74h+_Val.end.face]
.text:0042F733                 fdiv    ds:__real@40c3880000000000
.text:0042F739                 fstp    dword ptr [ebp+74h+var_3C+8] // state.GetValue(4) + (state.GetLevel() * state.GetValue(5))
.text:0042F73C                 mov     this, esi       ; this
.text:0042F73E                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
.text:0042F743                 mov     this, esi       ; this
.text:0042F745                 push    eax             ; n
.text:0042F746                 lea     eax, [ebp+74h+var_9D8]
.text:0042F74C                 push    eax             ; result
.text:0042F74D                 push    7               ; idx
.text:0042F74F                 lea     eax, [ebp+74h+var_288]
.text:0042F755                 push    eax             ; result
.text:0042F756                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F75B                 mov     this, eax       ; this
.text:0042F75D                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
.text:0042F762                 mov     ebx, eax
.text:0042F764                 push    6               ; idx
.text:0042F766                 lea     eax, [ebp+74h+var_D88]
.text:0042F76C                 push    eax             ; result
.text:0042F76D                 mov     this, esi       ; this
.text:0042F76F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F774                 mov     this, [ebx]
.text:0042F776                 add     this, [eax] // state.GetValue(6) + (state.GetLevel() * state.GetValue(7))
.text:0042F778                 mov     edx, [ebx+4]
.text:0042F77B                 adc     edx, [eax+4] // state.GetValue(6) + (state.GetLevel() * state.GetValue(7))
.text:0042F77E                 mov     [ebp+74h+_Val.end.face], this // state.GetValue(6) + (state.GetLevel() * state.GetValue(7))
.text:0042F781                 mov     [ebp+74h+_Val.end_time], edx
.text:0042F784                 fild    qword ptr [ebp+74h+_Val.end.face]
.text:0042F787                 mov     this, esi       ; this
.text:0042F789                 fdiv    ds:__real@40c3880000000000
.text:0042F78F                 fstp    dword ptr [ebp+74h+var_28+4] // state.GetValue(6) + (state.GetLevel() * state.GetValue(7))
.text:0042F792                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
.text:0042F797                 mov     this, esi       ; this
.text:0042F799                 push    eax             ; n
.text:0042F79A                 lea     eax, [ebp+74h+var_298]
.text:0042F7A0                 push    eax             ; result
.text:0042F7A1                 push    9               ; idx
.text:0042F7A3                 lea     eax, [ebp+74h+var_9E8]
.text:0042F7A9                 push    eax             ; result
.text:0042F7AA                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F7AF                 mov     this, eax       ; this
.text:0042F7B1                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
.text:0042F7B6                 mov     ebx, eax
.text:0042F7B8                 push    8               ; idx
.text:0042F7BA                 lea     eax, [ebp+74h+var_2A8]
.text:0042F7C0                 push    eax             ; result
.text:0042F7C1                 mov     this, esi       ; this
.text:0042F7C3                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F7C8                 mov     this, [eax]
.text:0042F7CA                 add     this, [ebx] // state.GetValue(8) + (state.GetLevel() * state.GetValue(9))
.text:0042F7CC                 mov     eax, [eax+4]
.text:0042F7CF                 adc     eax, [ebx+4] // state.GetValue(8) + (state.GetLevel() * state.GetValue(9))
.text:0042F7D2                 mov     [ebp+74h+_Val.end.face], this
.text:0042F7D5                 mov     [ebp+74h+_Val.end_time], eax
.text:0042F7D8                 fild    qword ptr [ebp+74h+_Val.end.face]
.text:0042F7DB                 mov     this, esi       ; this
.text:0042F7DD                 fdiv    ds:__real@40c3880000000000
.text:0042F7E3                 fstp    [ebp+74h+_Val.end_time] // state.GetValue(8) + (state.GetLevel() * state.GetValue(9))
.text:0042F7E6                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
.text:0042F7EB                 mov     this, esi       ; this
.text:0042F7ED                 push    eax             ; n
.text:0042F7EE                 lea     eax, [ebp+74h+var_1048]
.text:0042F7F4                 push    eax             ; result
.text:0042F7F5                 push    0Bh             ; idx
.text:0042F7F7                 lea     eax, [ebp+74h+var_2B8]
.text:0042F7FD                 push    eax             ; result
.text:0042F7FE                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F803                 mov     this, eax       ; this
.text:0042F805                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
.text:0042F80A                 push    0Ah             ; idx
.text:0042F80C                 lea     eax, [ebp+74h+var_9F8]
.text:0042F812                 push    eax             ; result
.text:0042F813                 mov     this, esi       ; this
.text:0042F815                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
.text:0042F81A                 mov     esi, [esi+StructState.m_nCode]
.text:0042F81D                 mov     eax, 1780h
.text:0042F822                 cmp     esi, eax
.text:0042F824                 jg      loc_42FA50
.text:0042F82A                 jz      loc_42FA20
.text:0042F830                 add     eax, 0FFFFFFF7h
.text:0042F833                 cmp     esi, eax
.text:0042F835                 jg      loc_42F998
.text:0042F83B                 jz      loc_42FCBB
.text:0042F841                 cmp     esi, 3FDh
.text:0042F847                 jz      loc_42F979
.text:0042F84D                 cmp     esi, 803h
.text:0042F853                 jz      loc_42F967
.text:0042F859                 cmp     esi, 1195h
.text:0042F85F                 jz      loc_42F8F3
.text:0042F865                 cmp     esi, 1197h
.text:0042F86B                 jz      short loc_42F88A
.text:0042F86D                 cmp     esi, 1774h
.text:0042F873                 jle     loc_4341E4
.text:0042F879                 cmp     esi, 1776h
.text:0042F87F
.text:0042F87F loc_42F87F:                             ; CODE XREF: StructCreature::applyState(StructState &)+D78j
.text:0042F87F                 jle     loc_42FCAF
.text:0042F885                 jmp     loc_4341E4
*/

                    break;

                case 1:
                    this.incParameter((uint)state.GetValue(0),(int)(state.GetValue(1) + (state.GetValue(2) * state.GetLevel())),false);
                    this.incParameter((uint)state.GetValue(3),(int)(state.GetValue(4) + (state.GetValue(5) * state.GetLevel())),false);
                    this.incParameter2((uint)state.GetValue(6),(int)(state.GetValue(7) + (state.GetValue(8) * state.GetLevel())));
                    this.incParameter2((uint)state.GetValue(9),(int)(state.GetValue(10) + (state.GetValue(11) * state.GetLevel())));
                    this.incParameter((uint)state.GetValue(12),(int)(state.GetValue(13) + (state.GetValue(14) * state.GetLevel())),false);
                    this.incParameter((uint)state.GetValue(15),(int)(state.GetValue(16) + (state.GetValue(17) * state.GetLevel())),false);
                    break;

                case 2:

                    break;

                case 44:
//.text:0042EEA4                 jz      loc_431D29
                    break;
             
                case 25:
//.text:0042EEB3                 jz      loc_4309C8 // jump if 25
                    break;

                case 6:

                case 74:
                    this.m_RangeStatePenalty.fDamage += (state.GetValue(0) + (state.GetValue(1) * state.GetLevel()));
                    this.m_NormalStatePenalty.fDamage += (state.GetValue(0) + (state.GetValue(1) * state.GetLevel()));
                    this.m_MagicalSkillStatePenalty.fDamage += (state.GetValue(2) + (state.GetValue(3) * state.GetLevel()));
                    break;
            }
            
// .text:0042EE7D                 push    ebp
// .text:0042EE7E                 lea     ebp, [esp-74h]
// .text:0042EE82                 mov     eax, 1190h
// .text:0042EE87                 call    __chkstk
// .text:0042EE8C                 push    ebx
// .text:0042EE8D                 push    esi
// .text:0042EE8E                 mov     esi, state
// .text:0042EE91                 push    edi
// .text:0042EE92                 mov     edi, this
// .text:0042EE94                 mov     this, esi       ; this
// .text:0042EE96                 call    ?GetEffectType@StructState@@QBEHXZ ; StructState::GetEffectType(void)
// .text:0042EE9B                 cmp     eax, 44  // 44
// .text:0042EE9E                 jg      loc_431E62 // jump if higher than 44
// .text:0042EEA4                 jz      loc_431D29 // jump if 44
// .text:0042EEAA                 cmp     eax, 25  // 25
// .text:0042EEAD                 jg      loc_430C5D // jump if highter than 25
// .text:0042EEB3                 jz      loc_4309C8 // jump if 25
// .text:0042EEB9                 cmp     eax, 6
// .text:0042EEBC                 jg      loc_430108 // jump if higher than 6
// .text:0042EEC2                 cmp     eax, 5
// .text:0042EEC5                 jge     loc_42FCCA // jump if 5 or 6
// .text:0042EECB                 sub     eax, 0
// .text:0042EECE                 jz      loc_42F640 // jump if 0
// .text:0042EED4                 dec     eax
// .text:0042EED5                 jz      loc_42F30F // jump if 1
// .text:0042EEDB                 dec     eax // 2
// .text:0042EEDC                 dec     eax // 3
// .text:0042EEDD                 jz      loc_42F0E5 // jump if 3
// .text:0042EEE3                 dec     eax // 4
// .text:0042EEE4                 jnz     loc_4341E4 // jump if not 4 (must be 2)
// .text:0042EEEA                 mov     this, edi       ; this
// .text:0042EEEC                 call    ?IsWearShield@StructCreature@@QBE_NXZ ; StructCreature::IsWearShield(void)
// .text:0042EEF1                 test    al, al
// .text:0042EEF3                 jz      loc_4341E4
// .text:0042EEF9                 push    0
// .text:0042EEFB                 mov     this, esi       ; this
// .text:0042EEFD                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042EF02                 mov     this, esi       ; this
// .text:0042EF04                 push    eax             ; n
// .text:0042EF05                 lea     eax, [ebp+74h+var_10A8]
// .text:0042EF0B                 push    eax             ; result
// .text:0042EF0C                 push    2               ; idx
// .text:0042EF0E                 lea     eax, [ebp+74h+result]
// .text:0042EF14                 push    eax             ; result
// .text:0042EF15                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EF1A                 mov     this, eax       ; this
// .text:0042EF1C                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042EF21                 push    this
// .text:0042EF22                 push    this
// .text:0042EF23                 mov     ebx, esp
// .text:0042EF25                 mov     [ebp+74h+fValue1], eax
// .text:0042EF28                 push    1               ; idx
// .text:0042EF2A                 lea     eax, [ebp+74h+var_88]
// .text:0042EF2D                 push    eax             ; result
// .text:0042EF2E                 mov     this, esi       ; this
// .text:0042EF30                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EF35                 and     dword ptr [ebx], 0
// .text:0042EF38                 and     dword ptr [ebx+4], 0
// .text:0042EF3C                 mov     this, [ebp+74h+fValue1]
// .text:0042EF3F                 mov     edx, [this]
// .text:0042EF41                 add     edx, [eax]
// .text:0042EF43                 mov     this, [this+4]
// .text:0042EF46                 adc     this, [eax+4]
// .text:0042EF49                 push    0               ; idx
// .text:0042EF4B                 lea     eax, [ebp+74h+var_D08]
// .text:0042EF51                 mov     [ebx+4], this
// .text:0042EF54                 push    eax             ; result
// .text:0042EF55                 mov     this, esi       ; this
// .text:0042EF57                 mov     [ebx], edx
// .text:0042EF59                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EF5E                 fild    qword ptr [eax]
// .text:0042EF60                 mov     ebx, [edi]
// .text:0042EF62                 fdiv    ds:__real@40c3880000000000
// .text:0042EF68                 call    __ftol2_sse
// .text:0042EF6D                 push    eax
// .text:0042EF6E                 mov     this, edi
// .text:0042EF70                 call    dword ptr [ebx+12Ch]
// .text:0042EF76                 push    0
// .text:0042EF78                 mov     this, esi       ; this
// .text:0042EF7A                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042EF7F                 mov     this, esi       ; this
// .text:0042EF81                 push    eax             ; n
// .text:0042EF82                 lea     eax, [ebp+74h+var_98]
// .text:0042EF85                 push    eax             ; result
// .text:0042EF86                 push    5               ; idx
// .text:0042EF88                 lea     eax, [ebp+74h+var_8E8]
// .text:0042EF8E                 push    eax             ; result
// .text:0042EF8F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EF94                 mov     this, eax       ; this
// .text:0042EF96                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042EF9B                 push    this
// .text:0042EF9C                 push    this
// .text:0042EF9D                 mov     ebx, esp
// .text:0042EF9F                 mov     [ebp+74h+fValue1], eax
// .text:0042EFA2                 push    4               ; idx
// .text:0042EFA4                 lea     eax, [ebp+74h+var_A8]
// .text:0042EFA7                 push    eax             ; result
// .text:0042EFA8                 mov     this, esi       ; this
// .text:0042EFAA                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EFAF                 and     dword ptr [ebx], 0
// .text:0042EFB2                 and     dword ptr [ebx+4], 0
// .text:0042EFB6                 mov     this, [ebp+74h+fValue1]
// .text:0042EFB9                 mov     edx, [this]
// .text:0042EFBB                 add     edx, [eax]
// .text:0042EFBD                 mov     this, [this+4]
// .text:0042EFC0                 adc     this, [eax+4]
// .text:0042EFC3                 push    3               ; idx
// .text:0042EFC5                 lea     eax, [ebp+74h+var_1028]
// .text:0042EFCB                 mov     [ebx+4], this
// .text:0042EFCE                 push    eax             ; result
// .text:0042EFCF                 mov     this, esi       ; this
// .text:0042EFD1                 mov     [ebx], edx
// .text:0042EFD3                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042EFD8                 fild    qword ptr [eax]
// .text:0042EFDA                 fdiv    ds:__real@40c3880000000000
// .text:0042EFE0                 mov     ebx, [edi]
// .text:0042EFE2                 call    __ftol2_sse
// .text:0042EFE7                 push    eax
// .text:0042EFE8                 mov     this, edi
// .text:0042EFEA                 call    dword ptr [ebx+12Ch]
// .text:0042EFF0                 mov     this, esi       ; this
// .text:0042EFF2                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042EFF7                 mov     this, esi       ; this
// .text:0042EFF9                 push    eax             ; n
// .text:0042EFFA                 lea     eax, [ebp+74h+var_B8]
// .text:0042EFFD                 push    eax             ; result
// .text:0042EFFE                 push    8               ; idx
// .text:0042F000                 lea     eax, [ebp+74h+var_8F8]
// .text:0042F006                 push    eax             ; result
// .text:0042F007                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F00C                 mov     this, eax       ; this
// .text:0042F00E                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F013                 push    this
// .text:0042F014                 push    this
// .text:0042F015                 mov     ebx, esp
// .text:0042F017                 mov     [ebp+74h+fValue1], eax
// .text:0042F01A                 push    7               ; idx
// .text:0042F01C                 lea     eax, [ebp+74h+var_C8]
// .text:0042F01F                 push    eax             ; result
// .text:0042F020                 mov     this, esi       ; this
// .text:0042F022                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F027                 and     dword ptr [ebx], 0
// .text:0042F02A                 and     dword ptr [ebx+4], 0
// .text:0042F02E                 mov     this, [ebp+74h+fValue1]
// .text:0042F031                 mov     edx, [this]
// .text:0042F033                 add     edx, [eax]
// .text:0042F035                 mov     this, [this+4]
// .text:0042F038                 adc     this, [eax+4]
// .text:0042F03B                 push    6               ; idx
// .text:0042F03D                 lea     eax, [ebp+74h+var_D18]
// .text:0042F043                 mov     [ebx+4], this
// .text:0042F046                 push    eax             ; result
// .text:0042F047                 mov     this, esi       ; this
// .text:0042F049                 mov     [ebx], edx
// .text:0042F04B                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F050                 fild    qword ptr [eax]
// .text:0042F052                 mov     ebx, [edi]
// .text:0042F054                 fdiv    ds:__real@40c3880000000000
// .text:0042F05A                 call    __ftol2_sse
// .text:0042F05F                 push    eax
// .text:0042F060                 mov     this, edi
// .text:0042F062                 call    dword ptr [ebx+134h]
// .text:0042F068                 mov     this, esi       ; this
// .text:0042F06A                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F06F                 mov     this, esi       ; this
// .text:0042F071                 push    eax             ; n
// .text:0042F072                 lea     eax, [ebp+74h+var_D8]
// .text:0042F075                 push    eax             ; result
// .text:0042F076                 push    0Bh             ; idx
// .text:0042F078                 lea     eax, [ebp+74h+var_908]
// .text:0042F07E                 push    eax             ; result
// .text:0042F07F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F084                 mov     this, eax       ; this
// .text:0042F086                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F08B                 push    this
// .text:0042F08C                 push    this
// .text:0042F08D                 mov     ebx, esp
// .text:0042F08F                 mov     [ebp+74h+fValue1], eax
// .text:0042F092                 push    0Ah             ; idx
// .text:0042F094                 lea     eax, [ebp+74h+var_E8]
// .text:0042F097                 push    eax             ; result
// .text:0042F098                 mov     this, esi       ; this
// .text:0042F09A                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F09F                 and     dword ptr [ebx], 0
// .text:0042F0A2                 and     dword ptr [ebx+4], 0
// .text:0042F0A6                 mov     edx, [eax]
// .text:0042F0A8                 mov     this, [ebp+74h+fValue1]
// .text:0042F0AB                 add     edx, [this]
// .text:0042F0AD                 mov     eax, [eax+4]
// .text:0042F0B0                 adc     eax, [this+4]
// .text:0042F0B3                 push    9               ; idx
// .text:0042F0B5                 mov     [ebx+4], eax
// .text:0042F0B8                 lea     eax, [ebp+74h+var_F28]
// .text:0042F0BE                 mov     [ebx], edx
// .text:0042F0C0                 push    eax             ; result
// .text:0042F0C1                 mov     this, esi       ; this
// .text:0042F0C3                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F0C8                 fild    qword ptr [eax]
// .text:0042F0CA                 mov     esi, [edi]
// .text:0042F0CC                 fdiv    ds:__real@40c3880000000000
// .text:0042F0D2                 call    __ftol2_sse
// .text:0042F0D7                 push    eax
// .text:0042F0D8                 mov     this, edi
// .text:0042F0DA                 call    dword ptr [esi+134h]
// .text:0042F0E0                 jmp     loc_4341E4
// .text:0042F0E5 ; ---------------------------------------------------------------------------
// .text:0042F0E5
// .text:0042F0E5 loc_42F0E5:                             ; CODE XREF: StructCreature::applyState(StructState &)+60j
// .text:0042F0E5                 mov     this, edi       ; this
// .text:0042F0E7                 call    ?IsWearShield@StructCreature@@QBE_NXZ ; StructCreature::IsWearShield(void)
// .text:0042F0EC                 test    al, al
// .text:0042F0EE                 jz      loc_4341E4
// .text:0042F0F4                 mov     this, esi       ; this
// .text:0042F0F6                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F0FB                 mov     this, esi       ; this
// .text:0042F0FD                 push    eax             ; n
// .text:0042F0FE                 lea     eax, [ebp+74h+var_F8]
// .text:0042F104                 push    eax             ; result
// .text:0042F105                 push    2               ; idx
// .text:0042F107                 lea     eax, [ebp+74h+var_918]
// .text:0042F10D                 push    eax             ; result
// .text:0042F10E                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F113                 mov     this, eax       ; this
// .text:0042F115                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F11A                 mov     ebx, eax
// .text:0042F11C                 push    1               ; idx
// .text:0042F11E                 lea     eax, [ebp+74h+var_108]
// .text:0042F124                 push    eax             ; result
// .text:0042F125                 mov     this, esi       ; this
// .text:0042F127                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F12C                 mov     this, [ebx]
// .text:0042F12E                 add     this, [eax]
// .text:0042F130                 mov     edx, [ebx+4]
// .text:0042F133                 adc     edx, [eax+4]
// .text:0042F136                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F139                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F13C                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F13F                 push    0               ; idx
// .text:0042F141                 lea     eax, [ebp+74h+var_D28]
// .text:0042F147                 fdiv    ds:__real@40c3880000000000
// .text:0042F14D                 push    eax             ; result
// .text:0042F14E                 mov     this, esi       ; this
// .text:0042F150                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F153                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F158                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F15B                 mov     ebx, [edi]
// .text:0042F15D                 push    0
// .text:0042F15F                 mov     [ebp+74h+fValue1], eax
// .text:0042F162                 call    __ftol2_sse
// .text:0042F167                 push    eax
// .text:0042F168                 mov     eax, [ebp+74h+fValue1]
// .text:0042F16B                 fild    qword ptr [eax]
// .text:0042F16D                 fdiv    ds:__real@40c3880000000000
// .text:0042F173                 call    __ftol2_sse
// .text:0042F178                 push    eax
// .text:0042F179                 mov     this, edi
// .text:0042F17B                 call    dword ptr [ebx+128h]
// .text:0042F181                 mov     this, esi       ; this
// .text:0042F183                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F188                 mov     this, esi       ; this
// .text:0042F18A                 push    eax             ; n
// .text:0042F18B                 lea     eax, [ebp+74h+var_118]
// .text:0042F191                 push    eax             ; result
// .text:0042F192                 push    5               ; idx
// .text:0042F194                 lea     eax, [ebp+74h+var_928]
// .text:0042F19A                 push    eax             ; result
// .text:0042F19B                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F1A0                 mov     this, eax       ; this
// .text:0042F1A2                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F1A7                 mov     ebx, eax
// .text:0042F1A9                 push    4               ; idx
// .text:0042F1AB                 lea     eax, [ebp+74h+var_128]
// .text:0042F1B1                 push    eax             ; result
// .text:0042F1B2                 mov     this, esi       ; this
// .text:0042F1B4                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F1B9                 mov     this, [ebx]
// .text:0042F1BB                 add     this, [eax]
// .text:0042F1BD                 mov     edx, [ebx+4]
// .text:0042F1C0                 adc     edx, [eax+4]
// .text:0042F1C3                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F1C6                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F1C9                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F1CC                 push    3               ; idx
// .text:0042F1CE                 lea     eax, [ebp+74h+var_1108]
// .text:0042F1D4                 fdiv    ds:__real@40c3880000000000
// .text:0042F1DA                 push    eax             ; result
// .text:0042F1DB                 mov     this, esi       ; this
// .text:0042F1DD                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F1E0                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F1E5                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F1E8                 mov     ebx, [edi]
// .text:0042F1EA                 mov     [ebp+74h+fValue1], eax
// .text:0042F1ED                 push    0
// .text:0042F1EF                 call    __ftol2_sse
// .text:0042F1F4                 push    eax
// .text:0042F1F5                 mov     eax, [ebp+74h+fValue1]
// .text:0042F1F8                 fild    qword ptr [eax]
// .text:0042F1FA                 fdiv    ds:__real@40c3880000000000
// .text:0042F200                 call    __ftol2_sse
// .text:0042F205                 push    eax
// .text:0042F206                 mov     this, edi
// .text:0042F208                 call    dword ptr [ebx+128h]
// .text:0042F20E                 mov     this, esi       ; this
// .text:0042F210                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F215                 mov     this, esi       ; this
// .text:0042F217                 push    eax             ; n
// .text:0042F218                 lea     eax, [ebp+74h+var_138]
// .text:0042F21E                 push    eax             ; result
// .text:0042F21F                 push    8               ; idx
// .text:0042F221                 lea     eax, [ebp+74h+var_938]
// .text:0042F227                 push    eax             ; result
// .text:0042F228                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F22D                 mov     this, eax       ; this
// .text:0042F22F                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F234                 push    this
// .text:0042F235                 push    this
// .text:0042F236                 mov     ebx, esp
// .text:0042F238                 mov     [ebp+74h+fValue1], eax
// .text:0042F23B                 push    7               ; idx
// .text:0042F23D                 lea     eax, [ebp+74h+var_148]
// .text:0042F243                 push    eax             ; result
// .text:0042F244                 mov     this, esi       ; this
// .text:0042F246                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F24B                 and     dword ptr [ebx], 0
// .text:0042F24E                 and     dword ptr [ebx+4], 0
// .text:0042F252                 mov     this, [ebp+74h+fValue1]
// .text:0042F255                 mov     edx, [this]
// .text:0042F257                 add     edx, [eax]
// .text:0042F259                 mov     this, [this+4]
// .text:0042F25C                 adc     this, [eax+4]
// .text:0042F25F                 push    6               ; idx
// .text:0042F261                 lea     eax, [ebp+74h+var_D38]
// .text:0042F267                 mov     [ebx+4], this
// .text:0042F26A                 push    eax             ; result
// .text:0042F26B                 mov     this, esi       ; this
// .text:0042F26D                 mov     [ebx], edx
// .text:0042F26F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F274                 fild    qword ptr [eax]
// .text:0042F276                 mov     ebx, [edi]
// .text:0042F278                 fdiv    ds:__real@40c3880000000000
// .text:0042F27E                 call    __ftol2_sse
// .text:0042F283                 push    eax
// .text:0042F284                 mov     this, edi
// .text:0042F286                 call    dword ptr [ebx+130h]
// .text:0042F28C                 mov     this, esi       ; this
// .text:0042F28E                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F293                 mov     this, esi       ; this
// .text:0042F295                 push    eax             ; n
// .text:0042F296                 lea     eax, [ebp+74h+var_158]
// .text:0042F29C                 push    eax             ; result
// .text:0042F29D                 push    0Bh             ; idx
// .text:0042F29F                 lea     eax, [ebp+74h+var_948]
// .text:0042F2A5                 push    eax             ; result
// .text:0042F2A6                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F2AB                 mov     this, eax       ; this
// .text:0042F2AD                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F2B2                 push    this
// .text:0042F2B3                 push    this
// .text:0042F2B4                 mov     ebx, esp
// .text:0042F2B6                 mov     [ebp+74h+fValue1], eax
// .text:0042F2B9                 push    0Ah             ; idx
// .text:0042F2BB                 lea     eax, [ebp+74h+var_168]
// .text:0042F2C1                 push    eax             ; result
// .text:0042F2C2                 mov     this, esi       ; this
// .text:0042F2C4                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F2C9                 and     dword ptr [ebx], 0
// .text:0042F2CC                 and     dword ptr [ebx+4], 0
// .text:0042F2D0                 mov     this, [ebp+74h+fValue1]
// .text:0042F2D3                 mov     edx, [this]
// .text:0042F2D5                 add     edx, [eax]
// .text:0042F2D7                 mov     this, [this+4]
// .text:0042F2DA                 adc     this, [eax+4]
// .text:0042F2DD                 lea     eax, [ebp+74h+var_F38]
// .text:0042F2E3
// .text:0042F2E3 loc_42F2E3:                             ; CODE XREF: StructCreature::applyState(StructState &)+4C59j
// .text:0042F2E3                 push    9               ; idx
// .text:0042F2E5                 mov     [ebx+4], this
// .text:0042F2E8                 push    eax             ; result
// .text:0042F2E9                 mov     this, esi       ; this
// .text:0042F2EB                 mov     [ebx], edx
// .text:0042F2ED                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F2F2                 fild    qword ptr [eax]
// .text:0042F2F4                 mov     esi, [edi]
// .text:0042F2F6                 fdiv    ds:__real@40c3880000000000
// .text:0042F2FC                 call    __ftol2_sse
// .text:0042F301                 push    eax
// .text:0042F302                 mov     this, edi
// .text:0042F304                 call    dword ptr [esi+130h]
// .text:0042F30A                 jmp     loc_4341E4
// .text:0042F30F ; ---------------------------------------------------------------------------
// .text:0042F30F
// .text:0042F30F loc_42F30F:                             ; CODE XREF: StructCreature::applyState(StructState &)+58j
// .text:0042F30F                 mov     this, esi       ; this
// .text:0042F311                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F316                 mov     this, esi       ; this
// .text:0042F318                 push    eax             ; n
// .text:0042F319                 lea     eax, [ebp+74h+var_178]
// .text:0042F31F                 push    eax             ; result
// .text:0042F320                 push    2               ; idx
// .text:0042F322                 lea     eax, [ebp+74h+var_958]
// .text:0042F328                 push    eax             ; result
// .text:0042F329                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F32E                 mov     this, eax       ; this
// .text:0042F330                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F335                 mov     ebx, eax
// .text:0042F337                 push    1               ; idx
// .text:0042F339                 lea     eax, [ebp+74h+var_188]
// .text:0042F33F                 push    eax             ; result
// .text:0042F340                 mov     this, esi       ; this
// .text:0042F342                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F347                 mov     this, [ebx]
// .text:0042F349                 add     this, [eax]
// .text:0042F34B                 mov     edx, [ebx+4]
// .text:0042F34E                 adc     edx, [eax+4]
// .text:0042F351                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F354                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F357                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F35A                 push    0               ; idx
// .text:0042F35C                 lea     eax, [ebp+74h+var_D48]
// .text:0042F362                 fdiv    ds:__real@40c3880000000000
// .text:0042F368                 push    eax             ; result
// .text:0042F369                 mov     this, esi       ; this
// .text:0042F36B                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F36E                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F373                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F376                 mov     ebx, [edi]
// .text:0042F378                 push    0
// .text:0042F37A                 mov     [ebp+74h+fValue1], eax
// .text:0042F37D                 call    __ftol2_sse
// .text:0042F382                 push    eax
// .text:0042F383                 mov     eax, [ebp+74h+fValue1]
// .text:0042F386                 fild    qword ptr [eax]
// .text:0042F388                 fdiv    ds:__real@40c3880000000000
// .text:0042F38E                 call    __ftol2_sse
// .text:0042F393                 push    eax
// .text:0042F394                 mov     this, edi
// .text:0042F396                 call    dword ptr [ebx+128h]
// .text:0042F39C                 mov     this, esi       ; this
// .text:0042F39E                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F3A3                 mov     this, esi       ; this
// .text:0042F3A5                 push    eax             ; n
// .text:0042F3A6                 lea     eax, [ebp+74h+var_198]
// .text:0042F3AC                 push    eax             ; result
// .text:0042F3AD                 push    5               ; idx
// .text:0042F3AF                 lea     eax, [ebp+74h+var_968]
// .text:0042F3B5                 push    eax             ; result
// .text:0042F3B6                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F3BB                 mov     this, eax       ; this
// .text:0042F3BD                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F3C2                 mov     ebx, eax
// .text:0042F3C4                 push    4               ; idx
// .text:0042F3C6                 lea     eax, [ebp+74h+var_1A8]
// .text:0042F3CC                 push    eax             ; result
// .text:0042F3CD                 mov     this, esi       ; this
// .text:0042F3CF                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F3D4                 mov     this, [ebx]
// .text:0042F3D6                 add     this, [eax]
// .text:0042F3D8                 mov     edx, [ebx+4]
// .text:0042F3DB                 adc     edx, [eax+4]
// .text:0042F3DE                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F3E1                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F3E4                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F3E7                 push    3               ; idx
// .text:0042F3E9                 lea     eax, [ebp+74h+var_1038]
// .text:0042F3EF                 fdiv    ds:__real@40c3880000000000
// .text:0042F3F5                 push    eax             ; result
// .text:0042F3F6                 mov     this, esi       ; this
// .text:0042F3F8                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F3FB                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F400                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F403                 mov     ebx, [edi]
// .text:0042F405                 mov     [ebp+74h+fValue1], eax
// .text:0042F408                 push    0
// .text:0042F40A                 call    __ftol2_sse
// .text:0042F40F                 push    eax
// .text:0042F410                 mov     eax, [ebp+74h+fValue1]
// .text:0042F413                 fild    qword ptr [eax]
// .text:0042F415                 fdiv    ds:__real@40c3880000000000
// .text:0042F41B                 call    __ftol2_sse
// .text:0042F420                 push    eax
// .text:0042F421                 mov     this, edi
// .text:0042F423                 call    dword ptr [ebx+128h]
// .text:0042F429                 mov     this, esi       ; this
// .text:0042F42B                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F430                 mov     this, esi       ; this
// .text:0042F432                 push    eax             ; n
// .text:0042F433                 lea     eax, [ebp+74h+var_1B8]
// .text:0042F439                 push    eax             ; result
// .text:0042F43A                 push    8               ; idx
// .text:0042F43C                 lea     eax, [ebp+74h+var_978]
// .text:0042F442                 push    eax             ; result
// .text:0042F443                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F448                 mov     this, eax       ; this
// .text:0042F44A                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F44F                 push    this
// .text:0042F450                 push    this
// .text:0042F451                 mov     ebx, esp
// .text:0042F453                 mov     [ebp+74h+fValue1], eax
// .text:0042F456                 push    7               ; idx
// .text:0042F458                 lea     eax, [ebp+74h+var_1C8]
// .text:0042F45E                 push    eax             ; result
// .text:0042F45F                 mov     this, esi       ; this
// .text:0042F461                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F466                 and     dword ptr [ebx], 0
// .text:0042F469                 and     dword ptr [ebx+4], 0
// .text:0042F46D                 mov     this, [ebp+74h+fValue1]
// .text:0042F470                 mov     edx, [this]
// .text:0042F472                 add     edx, [eax]
// .text:0042F474                 mov     this, [this+4]
// .text:0042F477                 adc     this, [eax+4]
// .text:0042F47A                 push    6               ; idx
// .text:0042F47C                 lea     eax, [ebp+74h+var_D58]
// .text:0042F482                 mov     [ebx+4], this
// .text:0042F485                 push    eax             ; result
// .text:0042F486                 mov     this, esi       ; this
// .text:0042F488                 mov     [ebx], edx
// .text:0042F48A                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F48F                 fild    qword ptr [eax]
// .text:0042F491                 mov     ebx, [edi]
// .text:0042F493                 fdiv    ds:__real@40c3880000000000
// .text:0042F499                 call    __ftol2_sse
// .text:0042F49E                 push    eax
// .text:0042F49F                 mov     this, edi
// .text:0042F4A1                 call    dword ptr [ebx+130h]
// .text:0042F4A7                 mov     this, esi       ; this
// .text:0042F4A9                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F4AE                 mov     this, esi       ; this
// .text:0042F4B0                 push    eax             ; n
// .text:0042F4B1                 lea     eax, [ebp+74h+var_1D8]
// .text:0042F4B7                 push    eax             ; result
// .text:0042F4B8                 push    0Bh             ; idx
// .text:0042F4BA                 lea     eax, [ebp+74h+var_988]
// .text:0042F4C0                 push    eax             ; result
// .text:0042F4C1                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F4C6                 mov     this, eax       ; this
// .text:0042F4C8                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F4CD                 push    this
// .text:0042F4CE                 push    this
// .text:0042F4CF                 mov     ebx, esp
// .text:0042F4D1                 mov     [ebp+74h+fValue1], eax
// .text:0042F4D4                 push    0Ah             ; idx
// .text:0042F4D6                 lea     eax, [ebp+74h+var_1E8]
// .text:0042F4DC                 push    eax             ; result
// .text:0042F4DD                 mov     this, esi       ; this
// .text:0042F4DF                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F4E4                 and     dword ptr [ebx], 0
// .text:0042F4E7                 and     dword ptr [ebx+4], 0
// .text:0042F4EB                 mov     this, [ebp+74h+fValue1]
// .text:0042F4EE                 mov     edx, [this]
// .text:0042F4F0                 add     edx, [eax]
// .text:0042F4F2                 mov     this, [this+4]
// .text:0042F4F5                 adc     this, [eax+4]
// .text:0042F4F8                 mov     [ebx], edx
// .text:0042F4FA                 mov     [ebx+4], this
// .text:0042F4FD                 push    9               ; idx
// .text:0042F4FF                 lea     eax, [ebp+74h+var_F48]
// .text:0042F505                 push    eax             ; result
// .text:0042F506                 mov     this, esi       ; this
// .text:0042F508                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F50D                 fild    qword ptr [eax]
// .text:0042F50F                 mov     ebx, [edi]
// .text:0042F511                 fdiv    ds:__real@40c3880000000000
// .text:0042F517                 call    __ftol2_sse
// .text:0042F51C                 push    eax
// .text:0042F51D                 mov     this, edi
// .text:0042F51F                 call    dword ptr [ebx+130h]
// .text:0042F525                 mov     this, esi       ; this
// .text:0042F527                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F52C                 mov     this, esi       ; this
// .text:0042F52E                 push    eax             ; n
// .text:0042F52F                 lea     eax, [ebp+74h+var_1F8]
// .text:0042F535                 push    eax             ; result
// .text:0042F536                 push    0Eh             ; idx
// .text:0042F538                 lea     eax, [ebp+74h+var_998]
// .text:0042F53E                 push    eax             ; result
// .text:0042F53F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F544                 mov     this, eax       ; this
// .text:0042F546                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F54B                 mov     ebx, eax
// .text:0042F54D                 push    0Dh             ; idx
// .text:0042F54F                 lea     eax, [ebp+74h+var_208]
// .text:0042F555                 push    eax             ; result
// .text:0042F556                 mov     this, esi       ; this
// .text:0042F558                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F55D                 mov     this, [ebx]
// .text:0042F55F                 add     this, [eax]
// .text:0042F561                 mov     edx, [ebx+4]
// .text:0042F564                 adc     edx, [eax+4]
// .text:0042F567                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F56A                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F56D                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F570                 push    0Ch             ; idx
// .text:0042F572                 lea     eax, [ebp+74h+var_D68]
// .text:0042F578                 fdiv    ds:__real@40c3880000000000
// .text:0042F57E                 push    eax             ; result
// .text:0042F57F                 mov     this, esi       ; this
// .text:0042F581                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F584                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F589                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F58C                 mov     ebx, [edi]
// .text:0042F58E                 push    0
// .text:0042F590                 mov     [ebp+74h+fValue1], eax
// .text:0042F593                 call    __ftol2_sse
// .text:0042F598                 push    eax
// .text:0042F599                 mov     eax, [ebp+74h+fValue1]
// .text:0042F59C                 fild    qword ptr [eax]
// .text:0042F59E                 fdiv    ds:__real@40c3880000000000
// .text:0042F5A4                 call    __ftol2_sse
// .text:0042F5A9                 push    eax
// .text:0042F5AA                 mov     this, edi
// .text:0042F5AC                 call    dword ptr [ebx+128h]
// .text:0042F5B2                 mov     this, esi       ; this
// .text:0042F5B4                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F5B9                 mov     this, esi       ; this
// .text:0042F5BB                 push    eax             ; n
// .text:0042F5BC                 lea     eax, [ebp+74h+var_218]
// .text:0042F5C2                 push    eax             ; result
// .text:0042F5C3                 push    11h             ; idx
// .text:0042F5C5                 lea     eax, [ebp+74h+var_9A8]
// .text:0042F5CB                 push    eax             ; result
// .text:0042F5CC                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F5D1                 mov     this, eax       ; this
// .text:0042F5D3                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F5D8                 mov     ebx, eax
// .text:0042F5DA                 push    10h             ; idx
// .text:0042F5DC                 lea     eax, [ebp+74h+var_228]
// .text:0042F5E2                 push    eax             ; result
// .text:0042F5E3                 mov     this, esi       ; this
// .text:0042F5E5                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F5EA                 mov     this, [ebx]
// .text:0042F5EC                 add     this, [eax]
// .text:0042F5EE                 mov     edx, [ebx+4]
// .text:0042F5F1                 adc     edx, [eax+4]
// .text:0042F5F4                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F5F7                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F5FA                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F5FD                 push    0Fh             ; idx
// .text:0042F5FF                 lea     eax, [ebp+74h+var_10B8]
// .text:0042F605                 push    eax             ; result
// .text:0042F606                 fdiv    ds:__real@40c3880000000000
// .text:0042F60C                 mov     this, esi       ; this
// .text:0042F60E                 fstp    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F611                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F616                 fld     qword ptr [ebp+74h+_Val.end.face]
// .text:0042F619                 mov     ebx, [edi]
// .text:0042F61B                 push    0
// .text:0042F61D                 mov     esi, eax
// .text:0042F61F                 call    __ftol2_sse
// .text:0042F624                 fild    qword ptr [esi]
// .text:0042F626                 push    eax
// .text:0042F627                 fdiv    ds:__real@40c3880000000000
// .text:0042F62D                 call    __ftol2_sse
// .text:0042F632                 push    eax
// .text:0042F633                 mov     this, edi
// .text:0042F635                 call    dword ptr [ebx+128h]
// .text:0042F63B                 jmp     loc_4341E4
// .text:0042F640 ; ---------------------------------------------------------------------------
// .text:0042F640
// .text:0042F640 loc_42F640:                             ; CODE XREF: StructCreature::applyState(StructState &)+51j
// .text:0042F640                 mov     this, esi       ; this
// .text:0042F642                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F647                 mov     this, esi       ; this
// .text:0042F649                 push    eax             ; n
// .text:0042F64A                 lea     eax, [ebp+74h+var_238]
// .text:0042F650                 push    eax             ; result
// .text:0042F651                 push    1               ; idx
// .text:0042F653                 lea     eax, [ebp+74h+var_9B8]
// .text:0042F659                 push    eax             ; result
// .text:0042F65A                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F65F                 mov     this, eax       ; this
// .text:0042F661                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F666                 mov     ebx, eax
// .text:0042F668                 push    0               ; idx
// .text:0042F66A                 lea     eax, [ebp+74h+var_248]
// .text:0042F670                 push    eax             ; result
// .text:0042F671                 mov     this, esi       ; this
// .text:0042F673                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F678                 mov     this, [eax]
// .text:0042F67A                 add     this, [ebx]
// .text:0042F67C                 mov     eax, [eax+4]
// .text:0042F67F                 adc     eax, [ebx+4]
// .text:0042F682                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F685                 mov     [ebp+74h+_Val.end_time], eax
// .text:0042F688                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F68B                 mov     this, esi       ; this
// .text:0042F68D                 fdiv    ds:__real@40c3880000000000
// .text:0042F693                 fstp    [ebp+74h+fValue1]
// .text:0042F696                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F69B                 mov     this, esi       ; this
// .text:0042F69D                 push    eax             ; n
// .text:0042F69E                 lea     eax, [ebp+74h+var_D78]
// .text:0042F6A4                 push    eax             ; result
// .text:0042F6A5                 push    3               ; idx
// .text:0042F6A7                 lea     eax, [ebp+74h+var_258]
// .text:0042F6AD                 push    eax             ; result
// .text:0042F6AE                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F6B3                 mov     this, eax       ; this
// .text:0042F6B5                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F6BA                 mov     ebx, eax
// .text:0042F6BC                 push    2               ; idx
// .text:0042F6BE                 lea     eax, [ebp+74h+var_9C8]
// .text:0042F6C4                 push    eax             ; result
// .text:0042F6C5                 mov     this, esi       ; this
// .text:0042F6C7                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F6CC                 mov     this, [ebx]
// .text:0042F6CE                 add     this, [eax]
// .text:0042F6D0                 mov     edx, [ebx+4]
// .text:0042F6D3                 adc     edx, [eax+4]
// .text:0042F6D6                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F6D9                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F6DC                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F6DF                 mov     this, esi       ; this
// .text:0042F6E1                 fdiv    ds:__real@40c3880000000000
// .text:0042F6E7                 fstp    [ebp+74h+fValue2]
// .text:0042F6EA                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F6EF                 mov     this, esi       ; this
// .text:0042F6F1                 push    eax             ; n
// .text:0042F6F2                 lea     eax, [ebp+74h+var_268]
// .text:0042F6F8                 push    eax             ; result
// .text:0042F6F9                 push    5               ; idx
// .text:0042F6FB                 lea     eax, [ebp+74h+var_F58]
// .text:0042F701                 push    eax             ; result
// .text:0042F702                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F707                 mov     this, eax       ; this
// .text:0042F709                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F70E                 mov     ebx, eax
// .text:0042F710                 push    4               ; idx
// .text:0042F712                 lea     eax, [ebp+74h+var_278]
// .text:0042F718                 push    eax             ; result
// .text:0042F719                 mov     this, esi       ; this
// .text:0042F71B                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F720                 mov     this, [eax]
// .text:0042F722                 add     this, [ebx]
// .text:0042F724                 mov     eax, [eax+4]
// .text:0042F727                 adc     eax, [ebx+4]
// .text:0042F72A                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F72D                 mov     [ebp+74h+_Val.end_time], eax
// .text:0042F730                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F733                 fdiv    ds:__real@40c3880000000000
// .text:0042F739                 fstp    dword ptr [ebp+74h+var_3C+8]
// .text:0042F73C                 mov     this, esi       ; this
// .text:0042F73E                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F743                 mov     this, esi       ; this
// .text:0042F745                 push    eax             ; n
// .text:0042F746                 lea     eax, [ebp+74h+var_9D8]
// .text:0042F74C                 push    eax             ; result
// .text:0042F74D                 push    7               ; idx
// .text:0042F74F                 lea     eax, [ebp+74h+var_288]
// .text:0042F755                 push    eax             ; result
// .text:0042F756                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F75B                 mov     this, eax       ; this
// .text:0042F75D                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F762                 mov     ebx, eax
// .text:0042F764                 push    6               ; idx
// .text:0042F766                 lea     eax, [ebp+74h+var_D88]
// .text:0042F76C                 push    eax             ; result
// .text:0042F76D                 mov     this, esi       ; this
// .text:0042F76F                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F774                 mov     this, [ebx]
// .text:0042F776                 add     this, [eax]
// .text:0042F778                 mov     edx, [ebx+4]
// .text:0042F77B                 adc     edx, [eax+4]
// .text:0042F77E                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F781                 mov     [ebp+74h+_Val.end_time], edx
// .text:0042F784                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F787                 mov     this, esi       ; this
// .text:0042F789                 fdiv    ds:__real@40c3880000000000
// .text:0042F78F                 fstp    dword ptr [ebp+74h+var_28+4]
// .text:0042F792                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F797                 mov     this, esi       ; this
// .text:0042F799                 push    eax             ; n
// .text:0042F79A                 lea     eax, [ebp+74h+var_298]
// .text:0042F7A0                 push    eax             ; result
// .text:0042F7A1                 push    9               ; idx
// .text:0042F7A3                 lea     eax, [ebp+74h+var_9E8]
// .text:0042F7A9                 push    eax             ; result
// .text:0042F7AA                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F7AF                 mov     this, eax       ; this
// .text:0042F7B1                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F7B6                 mov     ebx, eax
// .text:0042F7B8                 push    8               ; idx
// .text:0042F7BA                 lea     eax, [ebp+74h+var_2A8]
// .text:0042F7C0                 push    eax             ; result
// .text:0042F7C1                 mov     this, esi       ; this
// .text:0042F7C3                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F7C8                 mov     this, [eax]
// .text:0042F7CA                 add     this, [ebx]
// .text:0042F7CC                 mov     eax, [eax+4]
// .text:0042F7CF                 adc     eax, [ebx+4]
// .text:0042F7D2                 mov     [ebp+74h+_Val.end.face], this
// .text:0042F7D5                 mov     [ebp+74h+_Val.end_time], eax
// .text:0042F7D8                 fild    qword ptr [ebp+74h+_Val.end.face]
// .text:0042F7DB                 mov     this, esi       ; this
// .text:0042F7DD                 fdiv    ds:__real@40c3880000000000
// .text:0042F7E3                 fstp    [ebp+74h+_Val.end_time]
// .text:0042F7E6                 call    ?GetLevel@StructState@@QBEGXZ ; StructState::GetLevel(void)
// .text:0042F7EB                 mov     this, esi       ; this
// .text:0042F7ED                 push    eax             ; n
// .text:0042F7EE                 lea     eax, [ebp+74h+var_1048]
// .text:0042F7F4                 push    eax             ; result
// .text:0042F7F5                 push    0Bh             ; idx
// .text:0042F7F7                 lea     eax, [ebp+74h+var_2B8]
// .text:0042F7FD                 push    eax             ; result
// .text:0042F7FE                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F803                 mov     this, eax       ; this
// .text:0042F805                 call    ??$?DG@?$c_fixed@$0CHBA@@@QBE?AV0@G@Z ; c_fixed<10000>::operator*<ushort>(ushort)
// .text:0042F80A                 push    0Ah             ; idx
// .text:0042F80C                 lea     eax, [ebp+74h+var_9F8]
// .text:0042F812                 push    eax             ; result
// .text:0042F813                 mov     this, esi       ; this
// .text:0042F815                 call    ?GetValue@StructState@@QBE?AV?$c_fixed@$0CHBA@@@H@Z ; StructState::GetValue(int)
// .text:0042F81A                 mov     esi, [esi+8]
// .text:0042F81D                 mov     eax, 1780h
// .text:0042F822                 cmp     esi, eax
// .text:0042F824                 jg      loc_42FA50
// .text:0042F82A                 jz      loc_42FA20
// .text:0042F830                 add     eax, 0FFFFFFF7h
// .text:0042F833                 cmp     esi, eax
// .text:0042F835                 jg      loc_42F998
// .text:0042F83B                 jz      loc_42FCBB
// .text:0042F841                 cmp     esi, 3FDh
// .text:0042F847                 jz      loc_42F979
// .text:0042F84D                 cmp     esi, 803h
// .text:0042F853                 jz      loc_42F967
// .text:0042F859                 cmp     esi, 1195h
// .text:0042F85F                 jz      loc_42F8F3
// .text:0042F865                 cmp     esi, 1197h
// .text:0042F86B                 jz      short loc_42F88A
// .text:0042F86D                 cmp     esi, 1774h
// .text:0042F873                 jle     loc_4341E4
// .text:0042F879                 cmp     esi, 1776h
// .text:0042F87F
// .text:0042F87F loc_42F87F:                             ; CODE XREF: StructCreature::applyState(StructState &)+D78j
// .text:0042F87F                 jle     loc_42FCAF
// .text:0042F885                 jmp     loc_4341E4
// .text:0042F88A ; ---------------------------------------------------------------------------
// .text:0042F88A
// .text:0042F88A loc_42F88A:                             ; CODE XREF: StructCreature::applyState(StructState &)+9EEj
// .text:0042F88A                 fld     [ebp+74h+fValue1]
// .text:0042F88D                 push    this            ; n
// .text:0042F88E                 lea     this, [edi+37Ah] ; this
// .text:0042F894                 fstp    dword ptr [esp+0]
// .text:0042F897                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F89C                 push    19h             ; idx
// .text:0042F89E                 lea     this, [edi+404h] ; this
// .text:0042F8A4                 call    ?IsOn@?$XFlag@H$00@@QBE_NI@Z ; XFlag<int,1>::IsOn(uint)
// .text:0042F8A9                 test    al, al
// .text:0042F8AB                 jz      short loc_42F8BF
// .text:0042F8AD                 fld     [ebp+74h+fValue1]
// .text:0042F8B0                 push    this            ; n
// .text:0042F8B1                 lea     this, [edi+382h] ; this
// .text:0042F8B7                 fstp    dword ptr [esp+0]
// .text:0042F8BA                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F8BF
// .text:0042F8BF loc_42F8BF:                             ; CODE XREF: StructCreature::applyState(StructState &)+A2Ej
// .text:0042F8BF                 mov     eax, [edi]
// .text:0042F8C1                 mov     this, edi
// .text:0042F8C3                 call    dword ptr [eax+18h]
// .text:0042F8C6                 test    al, al
// .text:0042F8C8                 jz      short loc_42F8D3
// .text:0042F8CA                 cmp     dword ptr [edi+157Ch], 0
// .text:0042F8D1                 jnz     short loc_42F8E5
// .text:0042F8D3
// .text:0042F8D3 loc_42F8D3:                             ; CODE XREF: StructCreature::applyState(StructState &)+A4Bj
// .text:0042F8D3                 fld     [ebp+74h+fValue2]
// .text:0042F8D6                 push    this            ; n
// .text:0042F8D7                 lea     this, [edi+322h] ; this
// .text:0042F8DD                 fstp    dword ptr [esp+0]
// .text:0042F8E0                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F8E5
// .text:0042F8E5 loc_42F8E5:                             ; CODE XREF: StructCreature::applyState(StructState &)+A54j
// .text:0042F8E5                 mov     word ptr [edi+1DCh], 64h
// .text:0042F8EE                 jmp     loc_4341E4
// .text:0042F8F3 ; ---------------------------------------------------------------------------
// .text:0042F8F3
// .text:0042F8F3 loc_42F8F3:                             ; CODE XREF: StructCreature::applyState(StructState &)+9E2j
// .text:0042F8F3                 lea     esi, [edi+404h]
// .text:0042F8F9                 push    13h             ; idx
// .text:0042F8FB                 mov     this, esi       ; this
// .text:0042F8FD                 call    ?On@?$XFlag@H$00@@QAEXI@Z ; XFlag<int,1>::On(uint)
// .text:0042F902                 call    ?GetArTime@@YAKXZ ; GetArTime(void)
// .text:0042F907                 fld     [ebp+74h+fValue1]
// .text:0042F90A                 push    this            ; n
// .text:0042F90B                 lea     this, [edi+37Ah] ; this
// .text:0042F911                 fstp    dword ptr [esp+0]
// .text:0042F914                 mov     [edi+484h], eax
// .text:0042F91A                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F91F                 push    19h             ; idx
// .text:0042F921                 mov     this, esi       ; this
// .text:0042F923                 call    ?IsOn@?$XFlag@H$00@@QBE_NI@Z ; XFlag<int,1>::IsOn(uint)
// .text:0042F928                 test    al, al
// .text:0042F92A                 jz      short loc_42F93E
// .text:0042F92C                 fld     [ebp+74h+fValue1]
// .text:0042F92F                 push    this            ; n
// .text:0042F930                 lea     this, [edi+382h] ; this
// .text:0042F936                 fstp    dword ptr [esp+0]
// .text:0042F939                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F93E
// .text:0042F93E loc_42F93E:                             ; CODE XREF: StructCreature::applyState(StructState &)+AADj
// .text:0042F93E                 fld     [ebp+74h+fValue2]
// .text:0042F941                 push    this            ; n
// .text:0042F942                 lea     this, [edi+342h] ; this
// .text:0042F948                 fstp    dword ptr [esp+0]
// .text:0042F94B                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F950                 push    this            ; n
// .text:0042F951                 lea     this, [edi+322h] ; this
// .text:0042F957
// .text:0042F957 loc_42F957:                             ; CODE XREF: StructCreature::applyState(StructState &)+CC6j
// .text:0042F957                 fld     dword ptr [ebp+74h+var_3C+8]
// .text:0042F95A                 fstp    dword ptr [esp+0]
// .text:0042F95D                 call    ??$?YM@?$c_fixed@$0CHBA@@@QAEAAV0@M@Z ; c_fixed<10000>::operator+=<float>(float)
// .text:0042F962                 jmp     loc_4341E4

        }
        
        protected virtual void applyStateAmplify(State state)
        {
            int effectType = state.GetEffectType();
            int level = state.GetLevel();
            if (effectType != 0)
            {
                if (effectType == 2)
                {
                    this.ampParameter((uint)state.GetValue(0),(state.GetValue(1) + (state.GetValue(2) * level)),false);
                    this.ampParameter((uint)state.GetValue(3),(state.GetValue(4) + (state.GetValue(5) * level)),false);
                    this.ampParameter2((uint)state.GetValue(6),(state.GetValue(7) + (state.GetValue(8) * level)));
                    this.ampParameter2((uint)state.GetValue(9),(state.GetValue(10) + (state.GetValue(11) * level)));
                    this.ampParameter((uint)state.GetValue(12),(state.GetValue(13) + (state.GetValue(14) * level)),false);
                    this.ampParameter((uint)state.GetValue(15),(state.GetValue(16) + (state.GetValue(17) * level)),false);
                }
            }
            else
            {
                if (state.m_nCode == State.StateCode.SquallOfArrow)
                {
                    if(state.GetValue(1) == 0.0f)
                        this.m_StatusFlag |= StatusFlags.Movable;
                    else
                        this.m_StatusFlag &= ~StatusFlags.Movable;

                    if ((int)this.GetWeaponClass() == (int)state.GetValue(0))
                    {
                        this.m_AttributeAmplifier.fAttackSpeedRight += state.GetValue(2) + (state.GetValue(3) * level);
                        if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        {
                            this.m_AttributeAmplifier.fAttackSpeedLeft += state.GetValue(2) + (state.GetValue(3) * level);
                        }
                    }
                }
            }

        }


        protected virtual void incParameter(uint nBitset, float nValue, bool bStat)
        {
            if (bStat)
            {
                if ((nBitset & 1) != 0)
                    this.m_Stat.strength += nValue;
                if ((nBitset & 2) != 0)
                    this.m_Stat.vital += nValue;
                if ((nBitset & 4) != 0)
                    this.m_Stat.agility += nValue;
                if ((nBitset & 8) != 0)
                    this.m_Stat.dexterity += nValue;
                if ((nBitset & 0x10) != 0)
                    this.m_Stat.intelligence += nValue;
                if ((nBitset & 0x20) != 0)
                    this.m_Stat.mentality += nValue;
                if ((nBitset & 0x40) != 0)
                    this.m_Stat.luck += nValue;
            }
            else
            {
                if ((nBitset & 0x80) != 0)
                {
                    this.m_Attribute.nAttackPointRight += nValue;
                    this.m_nAttackPointRightWithoutWeapon += (short)nValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    {
                        this.m_Attribute.nAttackPointLeft += nValue;
                        this.m_nAttackPointLeftWithoutWeapon += (short)nValue;
                    }
                }
                if ((nBitset & 0x100) != 0)
                    this.m_Attribute.nMagicPoint += nValue;
                if ((nBitset & 0x200) != 0)
                    this.m_Attribute.nDefence += nValue;
                if ((nBitset & 0x400) != 0)
                    this.m_Attribute.nMagicDefence += nValue;
                if ((nBitset & 0x800) != 0)
                {
                    this.m_Attribute.nAttackSpeedRight += nValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        this.m_Attribute.nAttackSpeedLeft += nValue;
                }
                if ((nBitset & 0x1000) != 0)
                    this.m_Attribute.nCastingSpeed += nValue;
                if ((nBitset & 0x2000) != 0 && (this.m_StatusFlag & StatusFlags.MoveSpeedFixed) == 0)
                {
                    Player p = this as Player;
                    if (p != null || p.m_nRidingStateUid == 0)
                        this.m_Attribute.nMoveSpeed += nValue;
                }
                if ((nBitset & 0x4000) != 0)
                {
                    this.m_Attribute.nAccuracyRight += nValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        this.m_Attribute.nAccuracyLeft += nValue;
                }
                if ((nBitset & 0x8000) != 0)
                    this.m_Attribute.nMagicAccuracy += nValue;
                if ((nBitset & 0x10000) != 0)
                    this.m_Attribute.nCritical += (short)nValue;
                if ((nBitset & 0x20000) != 0)
                    this.m_Attribute.nBlockChance += nValue;
                if ((nBitset & 0x40000) != 0)
                    this.m_Attribute.nBlockDefence += nValue;
                if ((nBitset & 0x80000) != 0)
                    this.m_Attribute.nAvoid += nValue;
                if ((nBitset & 0x100000) != 0)
                    this.m_Attribute.nMagicAvoid += nValue;
                if ((nBitset & 0x200000) != 0)
                    this.m_nMaxHP += (int)nValue;
                if ((nBitset & 0x400000) != 0)
                    this.m_nMaxMP += (int)nValue;
                if ((nBitset & 0x1000000) != 0)
                    this.m_Attribute.nHPRegenPoint += nValue;
                if ((nBitset & 0x2000000) != 0)
                    this.m_Attribute.nMPRegenPoint += nValue;
                if ((nBitset & 0x8000000) != 0)
                    this.m_Attribute.nHPRegenPercentage += nValue;
                if ((nBitset & 0x10000000) != 0)
                    this.m_Attribute.nMPRegenPercentage += nValue;
                if ((nBitset & 0x40000000) != 0)
                    this.m_Attribute.nMaxWeight += nValue;
            }
        }

        protected void ampParameter(uint nBitset, float fValue, bool bStat)
        {
            if (bStat)
            {
                if ((nBitset & 1) != 0)
                {
                    this.m_StatAmplifier.strength += fValue;
                }
                if ((nBitset & 2) != 0)
                {
                    this.m_StatAmplifier.vital += fValue;
                }
                if ((nBitset & 4) != 0)
                {
                    this.m_StatAmplifier.agility += fValue;
                }
                if ((nBitset & 8) != 0)
                {
                    this.m_StatAmplifier.dexterity += fValue;
                }
                if ((nBitset & 0x10) != 0)
                {
                    this.m_StatAmplifier.intelligence += fValue;
                }
                if ((nBitset & 0x20) != 0)
                {
                    this.m_StatAmplifier.mentality += fValue;
                }
                if ((nBitset & 0x40) != 0)
                {
                    this.m_StatAmplifier.luck += fValue;
                }
            }
            else
            {
                Player p = this as Player;
                if ((nBitset & 0x80) != 0)
                {
                    this.m_AttributeAmplifier.fAttackPointRight += fValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    {
                        this.m_AttributeAmplifier.fAttackPointLeft += fValue;
                    }
                }
                if ((nBitset & 0x100) != 0)
                {
                    this.m_AttributeAmplifier.fMagicPoint += fValue;
                }
                if ((nBitset & 0x200) != 0)
                {
                    this.m_AttributeAmplifier.fDefence += fValue;
                }
                if ((nBitset & 0x400) != 0)
                {
                    this.m_AttributeAmplifier.fMagicDefence += fValue;
                }
                if ((nBitset & 0x800) != 0)
                {
                    this.m_AttributeAmplifier.fAttackSpeedRight += fValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    {
                        this.m_AttributeAmplifier.fAttackSpeedLeft += fValue;
                    }
                }
                if ((nBitset & 0x1000) != 0)
                {
                    this.m_AttributeAmplifier.fCastingSpeed += fValue;
                }
                if ((nBitset & 0x2000) != 0)
                {
                    if (p == null || p.m_nRidingStateUid == 0)
                    {
                        this.m_AttributeAmplifier.fMoveSpeed += fValue;
                    }
                }
                if ((nBitset & 0x4000) != 0)
                {
                    this.m_AttributeAmplifier.fAccuracyRight += fValue;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    {
                        this.m_AttributeAmplifier.fAccuracyLeft += fValue;
                    }
                }
                if ((nBitset & 0x8000) != 0)
                {
                    this.m_AttributeAmplifier.fMagicAccuracy += fValue;
                }
                if ((nBitset & 0x10000) != 0)
                {
                    this.m_AttributeAmplifier.fCritical += fValue;
                }
                if ((nBitset & 0x20000) != 0)
                {
                    this.m_AttributeAmplifier.fBlockChance += fValue;
                }
                if ((nBitset & 0x40000) != 0)
                {
                    this.m_AttributeAmplifier.fBlockDefence += fValue;
                }
                if ((nBitset & 0x100000) != 0)
                {
                    this.m_AttributeAmplifier.fMagicAvoid += fValue;
                }
                if ((nBitset & 0x200000) != 0)
                    this.m_fMaxHPAmplifier += fValue;

                if ((nBitset & 0x400000) != 0)
                    this.m_fMaxMPAmplifier += fValue;

                if ((nBitset & 0x1000000) != 0)
                {
                    this.m_AttributeAmplifier.fHPRegenPoint += fValue;
                }
                if ((nBitset & 0x2000000) != 0)
                {
                    this.m_AttributeAmplifier.fMPRegenPoint += fValue;
                }
                if ((nBitset & 0x8000000) != 0)
                {
                    this.m_AttributeAmplifier.fHPRegenPercentage += fValue;
                }
                if ((nBitset & 0x10000000) != 0)
                {
                    this.m_AttributeAmplifier.fMPRegenPercentage += fValue;
                }
                if ((nBitset & 0x40000000) != 0)
                {
                    this.m_AttributeAmplifier.fMaxWeight += fValue;
                }
            }
        }


        protected void incParameter2(uint nBitset, float fValue)
        {
            if ((nBitset & 1) != 0)
            {
                this.m_Resist.nResist[0] += (short)fValue;
            }
            if ((nBitset & 2) != 0)
            {
                this.m_Resist.nResist[1] += (short)fValue;
            }
            if ((nBitset & 4) != 0)
            {
                this.m_Resist.nResist[2] += (short)fValue;
            }
            if ((nBitset & 8) != 0)
            {
                this.m_Resist.nResist[3] += (short)fValue;
            }
            if ((nBitset & 0x10) != 0)
            {
                this.m_Resist.nResist[4] += (short)fValue;
            }
            if ((nBitset & 0x20) != 0)
            {
                this.m_Resist.nResist[5] += (short)fValue;
            }
            if ((nBitset & 0x40) != 0)
            {
                this.m_Resist.nResist[6] += (short)fValue;
            }
            if ((nBitset & 0x200000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeNone, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeNone, fValue));
            }
            if ((nBitset & 0x400000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeFire, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeFire, fValue));
            }
            if ((nBitset & 0x800000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWater, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWater, fValue));
            }
            if ((nBitset & 0x1000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWind, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWind, fValue));
            }
            if ((nBitset & 0x2000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeEarth, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeEarth, fValue));
            }
            if ((nBitset & 0x4000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeLight, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeLight, fValue));
            }
            if ((nBitset & 0x8000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeDark, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeDark, fValue));
            }
            if ((nBitset & 0x10000000) != 0)
                this.m_Attribute.nCriticalPower += fValue;
            if ((nBitset & 0x20000000) != 0)
                this.m_StatusFlag |= StatusFlags.HPRegenStopped;
            if ((nBitset & 0x40000000) != 0)
                this.m_StatusFlag |= StatusFlags.MPRegenStopped;
        }


        protected void ampParameter2(uint nBitset, float fValue)
        {
            if ((nBitset & 1) != 0)
            {
                this.m_ResistAmplifier.fResist[0] += fValue;
            }
            if ((nBitset & 2) != 0)
            {
                this.m_ResistAmplifier.fResist[1] += fValue;
            }
            if ((nBitset & 4) != 0)
            {
                this.m_ResistAmplifier.fResist[2] += fValue;
            }
            if ((nBitset & 8) != 0)
            {
                this.m_ResistAmplifier.fResist[3] += fValue;
            }
            if ((nBitset & 0x10) != 0)
            {
                this.m_ResistAmplifier.fResist[4] += fValue;
            }
            if ((nBitset & 0x20) != 0)
            {
                this.m_ResistAmplifier.fResist[5] += fValue;
            }
            if ((nBitset & 0x40) != 0)
            {
                this.m_ResistAmplifier.fResist[6] += fValue;
            }
            if ((nBitset & 0x200000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeNone, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeNone, fValue));
            }
            if ((nBitset & 0x400000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeFire, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeFire, fValue));
            }
            if ((nBitset & 0x800000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWater, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWater, fValue));
            }
            if ((nBitset & 0x1000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWind, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeWind, fValue));
            }
            if ((nBitset & 0x2000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeEarth, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeEarth, fValue));
            }
            if ((nBitset & 0x4000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeLight, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeLight, fValue));
            }
            if ((nBitset & 0x8000000) != 0)
            {
                this.m_vNormalAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeDark, fValue));
                this.m_vRangeAdditionalDamage.Add(new AdditionalDamageInfo(100, Elemental.Type.TypeNone, Elemental.Type.TypeDark, fValue));
            }
            if ((nBitset & 0x10000000) != 0)
            {
                this.m_AttributeAmplifier.fCriticalPower += fValue;
            }
            if ((nBitset & 0x20000000) != 0)
                this.m_StatusFlag |= StatusFlags.HPRegenStopped;
            if ((nBitset & 0x40000000) != 0)
                this.m_StatusFlag |= StatusFlags.MPRegenStopped;

        }

        protected virtual ushort putonItem(ItemBase.ItemWearType pos, Item item)
        {
            this.m_anWear[(int)pos] = item;
            item.m_Instance.nWearInfo = pos;
            item.m_bIsNeedUpdateToDB = true;
            item.m_hBindedTarget = this.GetHandle();
            item.m_bIsNeedUpdateToDB = true;
            if (item.IsBow() || item.IsCrossBow())
                this.m_nNextAttackMode = 1;
            if (this.IsPlayer())
            {
                Player p = this as Player;
                Messages.SendItemWearInfoMessage(p, this, item);
            }
            else if (this.IsSummon())
            {
                Summon s = (Summon)this;
                Messages.SendItemWearInfoMessage(s.m_master, this, item);
            }
            return 0;
        }

        protected static ushort putoffItem(Creature c, ItemBase.ItemWearType pos)
        {
            return c.putoffItem(pos);
        }

        protected virtual ushort putoffItem(ItemBase.ItemWearType pos)
        {
            Item item = this.m_anWear[(int)pos];

            item.m_Instance.nWearInfo = ItemBase.ItemWearType.WearNone;
            item.m_bIsNeedUpdateToDB = true;
            item.m_hBindedTarget = 0;
            this.m_anWear[(int)pos] = null;

            if (this.IsPlayer())
            {
                Player p = this as Player;
                Messages.SendItemWearInfoMessage(p, p, item);
            }
            if (this.IsSummon())
            {
                Summon s = (Summon)this;
                Messages.SendItemWearInfoMessage(s.m_master, this, item);
            }
            return 0;
        }

        protected virtual void calcAttribute(CreatureAttributeServer attribute)
        {
//            v2 = pAttribute;
//            v3 = this;
            float v;
            attribute.nCriticalPower = 80;
            attribute.nCritical += ((this.m_Stat.luck * 0.2f) + 3.0f);
            float bl = this.GetBattleLevel();
            float fcm = this.GetFCM();
            if (this.IsUsingBow() || this.IsUsingCrossBow())
            {
                v = (1.2f * this.m_Stat.agility) + (2.2f * this.m_Stat.dexterity) + (fcm * bl);
                attribute.nAttackPointRight += v;// GameRule.GetBowAttackPoint(this.m_Stat.strength, this.m_Stat.dexterity, bl, fcm);
            }
            else
            {
                v = (2.8f * this.m_Stat.strength) + (fcm * bl);// +9;
                attribute.nAttackPointRight += v;
                if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                {
                    attribute.nAttackPointLeft += v;// ((2 * this.m_Stat.strength) * fcm + bl);
                }
            }
            
            attribute.nMagicPoint += ((2 * this.m_Stat.intelligence) + (fcm * bl));//2*Int + 1*Lv + Equip + Skill + Buff 

            attribute.nItemChance += (this.m_Stat.luck * 0.2f);

            attribute.nDefence += ((1.6f * this.m_Stat.vital) + (fcm * bl));//(5/3)*Vit + 1*Lv + Equip + Skill + Buff 
            attribute.nMagicDefence += ((2 * this.m_Stat.mentality) + (fcm + bl));//2*Wis + 1*Lv + Equip + Skill + Buff 
            attribute.nMaxWeight += GameRule.GetMaxWeight(this.GetLevel(), this.m_Stat.strength);
            attribute.nAccuracyRight += ((this.m_Stat.dexterity) * 0.5f + (fcm + bl));//(1/2)*Dex + 1*Lv + Equip + Skill + Buff 
            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
            {
                attribute.nAccuracyLeft += ((this.m_Stat.dexterity) * 0.5f + (fcm + bl));
            }
            attribute.nMagicAccuracy += GameRule.GetMagicAccuracy(this.m_Stat.mentality, this.m_Stat.dexterity, fcm, bl);//(4/10)*Wis + (1/10)*Dex + 1*Lv + Equip + Skill + Buff 
            attribute.nAvoid += (this.m_Stat.agility * 0.5f * fcm + bl);//(1/2)*Agi + 1*Lv + Equip + Skill + Buff 
            attribute.nMagicAvoid += (this.m_Stat.mentality * 0.5f * fcm + bl);//(1/2)*Wis + 1*Lv + Equip + Skill + Buff 
            //v3->baseclass_0.baseclass_0.baseclass_0.vfptr[10].IsDeleteable((ArSchedulerObject *)v3);
            attribute.nAttackSpeedRight += (100 + (this.m_Stat.agility*0.1f));//100 + (1/10)*Agi + Equip + Skill + Buff 
            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
            {
                //v3->baseclass_0.baseclass_0.baseclass_0.vfptr[10].IsDeleteable((ArSchedulerObject *)v3);
                attribute.nAttackSpeedLeft += (100 + (this.m_Stat.agility * 0.1f));
            }
            if ((this.m_StatusFlag & StatusFlags.MoveSpeedFixed) == 0)
                attribute.nMoveSpeed += (120*fcm);//120 + Equip + Skill + Buff 
            attribute.nCastingSpeed += (100*fcm);//100 + Equip + Skill + Buff 
            attribute.nCoolTimeSpeed = 100;
            float d1 = (fcm*5.0f);//5 + Equip + Skill + Buff 
            attribute.nHPRegenPercentage += d1;
            attribute.nHPRegenPoint += ((2*fcm*bl)+48.0f);//2*Lv + 48 + Equip + Skill + Buff 
//            v3->baseclass_0.baseclass_0.baseclass_0.vfptr[10].IsDeleteable((ArSchedulerObject *)v3);
            attribute.nMPRegenPercentage += d1;//5 + Equip + Skill + Buff 
            attribute.nMPRegenPoint += ((2 * fcm * bl) + 48.0f + (4.1f*this.m_Stat.mentality));//4.1*Wis + 2*Lv + 48 + Equip + Skill + Buff 
            if (attribute.nAttackRange == 0)
                attribute.nAttackRange = 50;

        }

        protected void applyStatByItem()
        {
// .text:00424E94 this            = std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > ptr -28h
// .text:00424E94 itSetItemEffectInfo= std::_Vector_const_iterator<SetItemEffectInfo *,std::allocator<SetItemEffectInfo *> > ptr -20h
// .text:00424E94 _Right          = std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > ptr -18h
// .text:00424E94 i               = dword ptr -0Ch
// .text:00424E94 var_8           = dword ptr -8
// .text:00424E94 var_4           = dword ptr -4

            List<int> ref_list = new List<int>();
            for(int i1 = 0; i1 < 24; ++i1)
            {
                Item item1 = this.m_anWear[i1];
                if (item1 != null)
                {
                    ItemBase.ItemWearType iwt = (ItemBase.ItemWearType)i1;
                    if (TranslateWearPosition(ref iwt,item1,ref ref_list))
                    {
                        for(int i2 = 0; i2 < 4; ++i2)
                        {
                            short ot = item1.m_pItemBase.nOptType[i2];
                            uint bs = (uint)item1.m_pItemBase.fOptVar1[i2];
                            int fv = (int)item1.m_pItemBase.fOptVar2[i2];
                            if (ot == 96)
                                this.incParameter(bs,fv, true);
                        }

                        if (item1.m_pItemBase.nSocketCount > 0)
                        {
                            for(int i3 = 0; i3 < 4; ++i3)
                            {
                                if (item1.m_Instance.Socket[i3] != 0)
                                {
                                    ItemBaseServer itembs = Item.GetItemBase(item1.m_Instance.Socket[i3]);
                                    if (this.GetLevel() >= itembs.nMinLevel)
                                    {
                                        if (this.GetLevel() <= itembs.nMaxLevel && item1.m_Instance.nCurrentEndurance != 0)
                                        {
                                            for(int i2 = 0; i2 < 4; ++i2)
                                            {
                                                short ot = itembs.nOptType[i2];
                                                uint bs = (uint)itembs.fOptVar1[i2];
                                                int fv = (int)itembs.fOptVar2[i2];
                                                if (ot == 96)
                                                    this.incParameter(bs,fv, true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

/*
            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                &thisa,
                (unsigned int *)v1->m_vSetItemEffect._Myfirst,
                &v1->m_vSetItemEffect.baseclass_0.___u0.baseclass_0);
            itSetItemEffectInfo.baseclass_0.baseclass_0._Mycont = thisa.baseclass_0.baseclass_0._Mycont;
            v19 = (std::_Container_base *)&v1->m_vSetItemEffect;
            v18 = (unsigned int *)v1->m_vSetItemEffect._Mylast;
            itSetItemEffectInfo._Myptr = (SetItemEffectInfo **)thisa._Myptr;
            while ( 1 )
            {
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    (std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > *)&_Right,
                    v18,
                    v19);
                if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                         (std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > *)&itSetItemEffectInfo,
                         &_Right) )
                    break;
                v13 = 0;
                v26 = 84;
                do
                {
                    v14 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&itSetItemEffectInfo);
                    if ( *(_WORD *)(v26 + LODWORD(v14->end.x)) )
                    {
                        v15 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&itSetItemEffectInfo);
                        if ( *(_WORD *)(v26 + LODWORD(v15->end.x)) == 96 )
                        {
                            v23 = (double)*(signed __int64 *)(v13
                                                            + LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&itSetItemEffectInfo)->end.x)
                                                            + 124)
                                / 10000.0;
                            v16 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((std::_Vector_const_iterator<ArMoveVector::MOVE_INFO,std::allocator<ArMoveVector::MOVE_INFO> > *)&itSetItemEffectInfo);
                            v17 = v1->baseclass_0.baseclass_0.baseclass_0.vfptr;
                            thisa._Myptr = (unsigned int *)(v13 + LODWORD(v16->end.x) + 92);
                            v17[14].__vecDelDtor(
                                (ArSchedulerObject *)v1,
                                (signed int)((double)*(signed __int64 *)thisa._Myptr / 10000.0));
                        }
                    }
                    v26 += 2;
                    v13 += 8;
                }
                while ( v26 < 92 );
                std::_Vector_const_iterator<AutoAuctionInfo___std::allocator<AutoAuctionInfo__>>::operator__((std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > *)&itSetItemEffectInfo);
                v19 = (std::_Container_base *)&v1->m_vSetItemEffect;
                v18 = (unsigned int *)v1->m_vSetItemEffect._Mylast;
            }
*/
        }
        
        protected void amplifyStatByItem()
        {

        }

        protected void getAmplifiedStatByAmplifier(CreatureStat stat)
        {
            stat.strength = ((m_StatAmplifier.strength * stat.strength) + stat.strength);
            stat.vital = ((m_StatAmplifier.vital * stat.vital) + stat.vital);
            stat.dexterity = ((m_StatAmplifier.dexterity * stat.dexterity) + stat.dexterity);
            stat.agility = ((m_StatAmplifier.agility * stat.agility) + stat.agility);
            stat.intelligence = ((m_StatAmplifier.intelligence * stat.intelligence) + stat.intelligence);
            stat.mentality = ((m_StatAmplifier.mentality * stat.mentality) + stat.mentality);
            stat.luck = ((m_StatAmplifier.luck * stat.luck) + stat.luck);
        }

        protected void getAmplifiedAttributeByAmplifier(CreatureAttributeServer attribute)
        {
            attribute.nCritical += (this.m_AttributeAmplifier.fCritical * attribute.nCritical);
            attribute.nCriticalPower += (this.m_AttributeAmplifier.fCriticalPower * attribute.nCriticalPower);
            attribute.nAttackPointRight += (this.m_AttributeAmplifier.fAttackPointRight * attribute.nAttackPointRight);
            attribute.nAttackPointLeft += (this.m_AttributeAmplifier.fAttackPointLeft * attribute.nAttackPointLeft);
            attribute.nDefence += (this.m_AttributeAmplifier.fDefence * attribute.nDefence);
            attribute.nBlockDefence += (this.m_AttributeAmplifier.fBlockDefence * attribute.nBlockDefence);
            attribute.nMagicPoint += (this.m_AttributeAmplifier.fMagicPoint * attribute.nMagicPoint);
            attribute.nMagicDefence += (this.m_AttributeAmplifier.fMagicDefence * attribute.nMagicDefence);
            attribute.nAccuracyRight += (this.m_AttributeAmplifier.fAccuracyRight * attribute.nAccuracyRight);
            attribute.nAccuracyLeft += (this.m_AttributeAmplifier.fAccuracyLeft * attribute.nAccuracyLeft);
            attribute.nMagicAccuracy += (this.m_AttributeAmplifier.fMagicAccuracy * attribute.nMagicAccuracy);
            attribute.nAvoid += (this.m_AttributeAmplifier.fAvoid * attribute.nAvoid);;
            attribute.nMagicAvoid += (this.m_AttributeAmplifier.fMagicAvoid * attribute.nMagicAvoid);
            attribute.nBlockChance += (this.m_AttributeAmplifier.fBlockChance * attribute.nBlockChance);
            if ((this.m_StatusFlag & StatusFlags.MoveSpeedFixed) == 0)
                attribute.nMoveSpeed += (this.m_AttributeAmplifier.fMoveSpeed * attribute.nMoveSpeed);

            attribute.nAttackSpeed += (this.m_AttributeAmplifier.fAttackSpeed * attribute.nAttackSpeed);
            attribute.nAttackRange += (this.m_AttributeAmplifier.fAttackRange * attribute.nAttackRange);
            attribute.nMaxWeight += (short)(this.m_AttributeAmplifier.fMaxWeight * attribute.nMaxWeight);
            attribute.nCastingSpeed += (short)(this.m_AttributeAmplifier.fCastingSpeed * attribute.nCastingSpeed);
            attribute.nCoolTimeSpeed += (this.m_AttributeAmplifier.fCoolTimeSpeed * attribute.nCoolTimeSpeed);
            attribute.nItemChance += (this.m_AttributeAmplifier.fItemChance * attribute.nItemChance);
            attribute.nHPRegenPercentage += (this.m_AttributeAmplifier.fHPRegenPercentage * attribute.nHPRegenPercentage);
            attribute.nHPRegenPoint += (this.m_AttributeAmplifier.fHPRegenPoint * attribute.nHPRegenPoint);
            attribute.nMPRegenPercentage += (this.m_AttributeAmplifier.fMPRegenPercentage * attribute.nMPRegenPercentage);
            attribute.nMPRegenPoint += (this.m_AttributeAmplifier.fMPRegenPoint * attribute.nMPRegenPoint);
            attribute.nAttackSpeedRight += (this.m_AttributeAmplifier.fAttackSpeedRight * attribute.nAttackSpeedRight);
            attribute.nAttackSpeedLeft += (this.m_AttributeAmplifier.fAttackSpeedLeft * attribute.nAttackSpeedLeft);
            attribute.nDoubleAttackRatio += (this.m_AttributeAmplifier.fDoubleAttackRatio * attribute.nDoubleAttackRatio);
            attribute.nStunResistance += (this.m_AttributeAmplifier.fStunResistance * attribute.nStunResistance);
            attribute.nMoveSpeedDecreaseResistance += (this.m_AttributeAmplifier.fMoveSpeedDecreaseResistance * attribute.nMoveSpeedDecreaseResistance);
            attribute.nHPAdd += (this.m_AttributeAmplifier.fHPAdd * attribute.nHPAdd);
            attribute.nMPAdd += (this.m_AttributeAmplifier.fMPAdd * attribute.nMPAdd);
            attribute.nHPAddByItem += (this.m_AttributeAmplifier.fHPAddByItem * attribute.nHPAddByItem);
            attribute.nMPAddByItem += (this.m_AttributeAmplifier.fMPAddByItem * attribute.nMPAddByItem);
        }
        
        protected void getAmplifiedResistByAmplifier(CreatureElementalResist resist)
        {

        }

        protected virtual void applyStatByState()
        {
            int[] nOriginalLevel = new int[3];                                              // 32   20h
            int[] nLevel = new int[3];                                                      // 44   2Ch
            List<RappelzPair<int,int>> vDecreaseList = new List<RappelzPair<int,int>>();    // 56   38h
            int nDecreaseLevel;                                 // 112  70h
            int i;

            if (this.m_vStateList.Count > 0)
            {
                foreach (State s in this.m_vStateList)
                {
                    if (s.GetEffectType() == 84 ) // Strong Spirit
                    {
                        nDecreaseLevel = (int)(s.GetValue(0) + (s.GetValue(1) * s.GetLevel()));
                        for(i = 2; i < 11; ++i)
                        {
                            if (s.GetValue(i) == 0.0)
                                break;
                            vDecreaseList.Add(new RappelzPair<int,int>((int)s.GetValue(i),nDecreaseLevel));
                        }
                    }
                }
                foreach (State s in this.m_vStateList)
                {
                    nOriginalLevel[0] = s.m_nLevel[0];
                    nOriginalLevel[1] = s.m_nLevel[1];
                    nOriginalLevel[2] = s.m_nLevel[2];
                    foreach (RappelzPair<int,int> rp in vDecreaseList)
                    {
                        if (rp.First == (int)s.m_nCode)
                        {
//                             *(v1 + 44) = 0;
//                             *(v1 + 48) = 0;
//                             *(v1 + 52) = 0;
//                             *(v1 + 100) = 0;
//                             do
//                             {
//                                 v17 = *(v1 + *(v1 + 100) + 40)
//                                     - LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 80))->end.y);
//                                 *(v1 + *(v1 + 100) + 52) = v17;
//                                 if ( v17 < 0 )
//                                 {
//                                     LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 80))->end.y) = -v17;
//                                     *(v1 + *(v1 + 100) + 52) = 0;
//                                 }
//                                 *(v1 + 100) -= 4;
//                             }
//                             while ( *(v1 + 100) >= -8 );
//                             LOWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end.face) = *(v1 + 44);
//                             HIWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end.face) = *(v1 + 48);
//                             LOWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end_time) = *(v1 + 52);
//                             break;
                        }
                    }

                    if (s.GetLevel() != 0)
                    {
                        if (s.GetEffectType() == 1)
                        {
                            // format is 0 = bitset, 1 = base, 2 = add per level
                            this.incParameter((uint)s.GetValue(0),(int)(s.GetValue(1) + (s.GetValue(2) * s.GetLevel())), true);
                            this.incParameter((uint)s.GetValue(3),(int)(s.GetValue(4) + (s.GetValue(5) * s.GetLevel())), true);
                            this.incParameter((uint)s.GetValue(12),(int)(s.GetValue(13) + (s.GetValue(14) * s.GetLevel())), true);
                            this.incParameter((uint)s.GetValue(15),(int)(s.GetValue(16) + (s.GetValue(17) * s.GetLevel())), true);

                        }
                        else if (s.GetEffectType() == 3 && this.IsWearShield())
                        {
                            this.incParameter((uint)s.GetValue(0),(int)(s.GetValue(1) + (s.GetValue(2) * s.GetLevel())), true);
                            this.incParameter((uint)s.GetValue(3),(int)(s.GetValue(4) + (s.GetValue(5) * s.GetLevel())), true);
                        }
                    }
                    s.m_nLevel[0] = nOriginalLevel[0];
                    s.m_nLevel[1] = nOriginalLevel[1];
                    s.m_nLevel[2] = nOriginalLevel[2];
                }
            }

        }
        protected virtual void amplifyStatByState()
        {
            int[] nOriginalLevel = new int[3];                                              // 32   20h
            int[] nLevel = new int[3];                                                      // 44   2Ch
            List<RappelzPair<int,int>> vDecreaseList = new List<RappelzPair<int,int>>();    // 56   38h
            int nDecreaseLevel;                                 // 112  70h
            int i;

            if (this.m_vStateList.Count > 0)
            {
                foreach (State s in this.m_vStateList)
                {
                    if (s.GetEffectType() == 84 ) // Strong Spirit
                    {
                        nDecreaseLevel = (int)(s.GetValue(0) + (s.GetValue(1) * s.GetLevel()));
                        for(i = 2; i < 11; ++i)
                        {
                            if (s.GetValue(i) == 0.0)
                                break;
                            vDecreaseList.Add(new RappelzPair<int,int>((int)s.GetValue(i),nDecreaseLevel));
                        }
                    }
                }
                foreach (State s in this.m_vStateList)
                {
                    nOriginalLevel[0] = s.m_nLevel[0];
                    nOriginalLevel[1] = s.m_nLevel[1];
                    nOriginalLevel[2] = s.m_nLevel[2];
                    foreach (RappelzPair<int,int> rp in vDecreaseList)
                    {
                        if (rp.First == (int)s.m_nCode)
                        {
//                             *(v1 + 44) = 0;
//                             *(v1 + 48) = 0;
//                             *(v1 + 52) = 0;
//                             *(v1 + 100) = 0;
//                             do
//                             {
//                                 v17 = *(v1 + *(v1 + 100) + 40)
//                                     - LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 80))->end.y);
//                                 *(v1 + *(v1 + 100) + 52) = v17;
//                                 if ( v17 < 0 )
//                                 {
//                                     LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 80))->end.y) = -v17;
//                                     *(v1 + *(v1 + 100) + 52) = 0;
//                                 }
//                                 *(v1 + 100) -= 4;
//                             }
//                             while ( *(v1 + 100) >= -8 );
//                             LOWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end.face) = *(v1 + 44);
//                             HIWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end.face) = *(v1 + 48);
//                             LOWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 104))->end_time) = *(v1 + 52);
//                             break;
                        }
                    }

                    if (s.GetLevel() != 0)
                    {
                        if (s.GetEffectType() == 2)
                        {
                            // format is 0 = bitset, 1 = base, 2 = add per level
                            this.ampParameter((uint)s.GetValue(0),(int)(s.GetValue(1) + (s.GetValue(2) * s.GetLevel())), true);
                            this.ampParameter((uint)s.GetValue(3),(int)(s.GetValue(4) + (s.GetValue(5) * s.GetLevel())), true);
                            this.ampParameter((uint)s.GetValue(12),(int)(s.GetValue(13) + (s.GetValue(14) * s.GetLevel())), true);
                            this.ampParameter((uint)s.GetValue(15),(int)(s.GetValue(16) + (s.GetValue(17) * s.GetLevel())), true);

                        }
                    }
                    s.m_nLevel[0] = nOriginalLevel[0];
                    s.m_nLevel[1] = nOriginalLevel[1];
                    s.m_nLevel[2] = nOriginalLevel[2];
                }
            }

        }
// Typedef        :   , Type: class std::map<int,int,std::less<int>,std::allocator<std::pair<int const ,int> > >
        protected void checkAdditionalItemEffect()
        {
/*
            int v1; // ebp@0
            StructCreature *v2; // ecx@1
            int v3; // ebx@1
            int v4; // eax@1
            StructItem *v5; // edi@1
            bool v6; // zf@2
            unsigned int v7; // eax@5
            StructItem *v8; // esi@5
            int v9; // eax@8
            ItemBaseServer *v10; // eax@10
            int v11; // ecx@10
            std::pair<std::_Tree<std::_Tmap_traits<int,int,std::less<int>,std::allocator<std::pair<int const ,int> >,0> >::iterator,bool> *v12; // eax@10
            ItemBaseServer *v13; // eax@12
            int v14; // ecx@12
            TENV *const *v15; // eax@14
            ItemBaseServer *v16; // eax@15
            bool v17; // sf@15
            unsigned __int8 v18; // of@15
            ItemBaseServer *v19; // edi@18
            int v20; // ebx@21
            int v21; // eax@21
            std::_Tree<std::_Tmap_traits<int,int,std::less<int>,std::allocator<std::pair<int const ,int> >,0> > *v22; // ecx@22
            int v23; // edi@23
            int v24; // eax@23
            int v25; // edi@26
            TENV *const *v26; // eax@27
            ItemBaseServer *v27; // eax@29
            int v28; // ecx@29
            int v29; // eax@32
            const int *v30; // eax@38
            std::vector<SetItemEffectInfo *,std::allocator<SetItemEffectInfo *> > *v31; // esi@38
            unsigned int *v32; // ST00_4@38
            int v33; // esi@39
            int v34; // edi@39
            ArMoveVector::MOVE_INFO *v35; // eax@40
            unsigned int *i; // [sp-1Ch] [bp-94h]@38
            int v37; // [sp-18h] [bp-90h]@10
            int v38; // [sp-18h] [bp-90h]@23
            std::vector<SetItemEffectInfo *,std::allocator<SetItemEffectInfo *> > *v39; // [sp-18h] [bp-90h]@38

// .text:004366B5 itSetPartFlag   = std::_Tree<std::_Tmap_traits<int,int,std::less<int>,std::allocator<std::pair<int const ,int> >,0> >::iterator ptr  1Ch
// .text:004366B5 nWearIndex      = dword ptr  50h
// .text:004366B5 itSetItemEffect = std::_Vector_const_iterator<SetItemEffectInfo *,std::allocator<SetItemEffectInfo *> > ptr  54h
// .text:004366B5 it              = std::_Tree<std::_Tmap_traits<int,int,std::less<int>,std::allocator<std::pair<int const ,int> >,0> >::const_iterator ptr  5Ch
// .text:004366B5 mapSetPartFlag  = std::map<int,int,std::less<int>,std::allocator<std::pair<int const ,int> > > ptr  64h
// .text:004366B5 pvSetItemEffectInfo= dword ptr  70h
// .text:004366B5 bNeedToCheckSetItem= byte ptr  77h
            bool bNeedToCheckSetItem = true;
            int nWearIndex = 0;

            _EH_prolog3(0x24u);
            v3 = v2;
            *(v1 + 96) = v2;
            Item ci = this.m_anWear[2];
            Item li = null;
            if (ci == null || ci.m_pItemBase.nSetID == 0)
                bNeedToCheckSetItem = false;
            std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::_Init((v1 + 100));
            *(v1 - 4) = 0;
            do
            {
                ci = this.m_anWear[nWearIndex];
                if (ReferenceEquals(ci,li))
                    goto LABEL_36;
                if (bNeedToCheckSetItem)
                {
                    if (nWearIndex <= 3 )
                    {
                        v9 = ci.m_pItemBase->baseclass_0.nSetID;
                        if ( v9 != v5 )
                        {
                            if ( *(v1 + 108) == v5 )
                            {
                                v10 = ci.m_pItemBase;
                                v11 = ci.m_pItemBase.nSetPartFlag;
                                *(v1 + 68) = ci.m_pItemBase.nSetID;
                                v37 = v1 + 68;
                                *(v1 + 72) = v11;
                                v12 = v1;
                            }
                            else
                            {
                                *(v1 + 112) = v9;
                                std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::find(
                                    (v1 + 100),
                                    (v1 + 28),
                                    (v1 + 112));
                                std::_Tree<std::_Tmap_traits<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag_std::less<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>_std::allocator<std::pair<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_const_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag>>_0>>::const_iterator::const_iterator(
                                    (v1 + 12),
                                    *(v1 + 104),
                                    (v1 + 100));
                                if ( !std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                                          (v1 + 28),
                                          (v1 + 12)) )
                                {
                                    v15 = std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::const_iterator::operator_((v1 + 28));
                                    *(v15 + 1) |= ci.m_pItemBase->baseclass_0.nSetPartFlag;
                                    goto LABEL_15;
                                }
                                v13 = ci.m_pItemBase;
                                v14 = ci.m_pItemBase.nSetPartFlag;
                                *(v1 + 44) = ci.m_pItemBase.nSetID;
                                v37 = v1 + 44;
                                *(v1 + 48) = v14;
                                v12 = (v1 - 36);
                            }
                            std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::insert(
                                (v1 + 100),
                                v12,
                                v37);
                        }
                    }
                }
        LABEL_15:
                v16 = ci.m_pItemBase;
                v18 = __OFSUB__(ci.m_pItemBase.nSocketCount, v5);
                v6 = ci.m_pItemBase.nSocketCount == v5;
                v17 = ci.m_pItemBase.nSocketCount - v5 < 0;
                *(v1 + 112) = v5;
                if ( !((v17 ^ v18) | v6) )
                {
                    *(v1 + 88) = v8 + 300;
                    do
                    {
                        if ( **(v1 + 88) == v5
                          || (v19 = StructItem::GetItemBase(**(v1 + 88)), (*(*v3 + 72))(v3) < v19->baseclass_0.nMinLevel)
                          || (*(*v3 + 72))(v3) > v19->baseclass_0.nMaxLevel
                          || ci.m_Instance.nCurrentEndurance == 0)
                            goto LABEL_29;
                        v20 = &v19->baseclass_0.nSetID;
                        v21 = v19->baseclass_0.nSetID;
                        if ( v21 )
                        {
                            v22 = (v1 + 100);
                            if ( *(v1 + 108) )
                            {
                                std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::find(
                                    v22,
                                    (v1 + 60),
                                    &v19->baseclass_0.nSetID);
                                std::_Tree<std::_Tmap_traits<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag_std::less<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>_std::allocator<std::pair<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_const_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag>>_0>>::const_iterator::const_iterator(
                                    (v1 + 20),
                                    *(v1 + 104),
                                    (v1 + 100));
                                if ( !std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                                          (v1 + 60),
                                          (v1 + 20)) )
                                {
                                    v26 = std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::const_iterator::operator_((v1 + 60));
                                    *(v26 + 1) |= v19->baseclass_0.nSetPartFlag;
                                    goto LABEL_28;
                                }
                                v25 = v19->baseclass_0.nSetPartFlag;
                                *(v1 + 36) = *v20;
                                v38 = v1 + 36;
                                *(v1 + 40) = v25;
                                v24 = v1 - 48;
                                v22 = (v1 + 100);
                            }
                            else
                            {
                                v23 = v19->baseclass_0.nSetPartFlag;
                                *(v1 + 52) = v21;
                                v38 = v1 + 52;
                                *(v1 + 56) = v23;
                                v24 = v1 - 24;
                            }
                            std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::insert(
                                v22,
                                v24,
                                v38);
                        }
        LABEL_28:
                        v3 = *(v1 + 96);
        LABEL_29:
                        ++*(v1 + 112);
                        v27 = ci.m_pItemBase;
                        v28 = *(v1 + 112);
                        *(v1 + 88) += 4;
                        v5 = 0;
                    }
                    while ( v28 < ci.m_pItemBase.nSocketCount );
                }
                if (ci.m_pItemBase.nGroup == 1 && StructItem::GetElementalEffectType(v8) )
                {
                    v29 = ci.m_Instance.nElementalEffectAttackPoint;
                    if (nWearIndex == v5 )
                        *(v3 + 1252) += v29;
                    else
                        *(v3 + 1256) += v29;
                    *(v3 + 1260) += ci.m_Instance.nElementalEffectMagicPoint;
                }
        LABEL_36:
                ++nWearIndex;
            }
            while (nWearIndex < 24 );
            std::_Tree<std::_Tmap_traits<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag_std::less<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>_std::allocator<std::pair<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_const_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag>>_0>>::const_iterator::const_iterator(
                (v1 + 60),
                **(v1 + 104),
                (v1 + 100));
            *(v1 + 92) = *(v1 + 60);
            *(v1 + 96) = *(v1 + 64);
            while ( 1 )
            {
                std::_Tree<std::_Tmap_traits<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag_std::less<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>_std::allocator<std::pair<std::basic_string<char_std::char_traits<char>_std::allocator<char>>_const_XPropertySetBase<std::basic_string<char_std::char_traits<char>_std::allocator<char>>>::property_tag>>_0>>::const_iterator::const_iterator(
                    (v1 + 68),
                    *(v1 + 104),
                    (v1 + 100));
                if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                         (v1 + 92),
                         (v1 + 68)) )
                    break;
                v30 = std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::const_iterator::operator_((v1 + 92));
                v31 = GameContent::GetSetItemEffectInfoVector(*v30);
                v32 = v31->_Myfirst;
                *(v1 + 112) = v31;
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    (v1 + 84),
                    v32,
                    &v31->baseclass_0.___u0.baseclass_0);
                v39 = v31;
                for ( i = v31->_Mylast; ; i = v39->_Mylast )
                {
                    std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                        (v1 + 76),
                        i,
                        &v39->baseclass_0.___u0.baseclass_0);
                    if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                             (v1 + 84),
                             (v1 + 76)) )
                        break;
                    v33 = LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 84))->end.x)
                        + 4;
                    v34 = *v33 & *(std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::const_iterator::operator_((v1 + 92))
                                 + 1);
                    if ( v34 == *(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 84))->end.x)
                                + 4) )
                    {
                        v35 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 + 84));
                        std::vector<StructRoamer___std::allocator<StructRoamer__>>::push_back((v3 + 4048), v35);
                    }
                    std::_Vector_const_iterator<AutoAuctionInfo___std::allocator<AutoAuctionInfo__>>::operator__((v1 + 84));
                    v39 = *(v1 + 112);
                }
                std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::const_iterator::_Inc((v1 + 92));
            }
            *(v1 - 4) = -1;
            std::_Tree<std::_Tmap_traits<int_int_std::less<int>_std::allocator<std::pair<int_const_int>>_0>>::_Tidy((v1 + 100));
*/
        }
        
        protected virtual void applyJobLevelBonus()
        {

        }

        protected void applyItemEffect()
        {
            Item curitem = GetWornItem(ItemBase.ItemWearType.WearWeapon);
            if (curitem != null)
                this.m_Attribute.nAttackRange = curitem.m_pItemBase.nRange;
            Skill curskill = this.GetCurrentPassiveSkill(12005);
            if (curskill == null)
            {
                curskill = this.GetCurrentPassiveSkill(12004);
                if (curskill == null)
                {
                    curskill = this.GetCurrentPassiveSkill(12003);
                    if (curskill == null)
                    {
                        curskill = this.GetCurrentPassiveSkill(12002);
                        if (curskill == null)
                            curskill = this.GetCurrentPassiveSkill(12001);
                    }
                }
            }
            this.m_nUnitExpertLevel = 0;
            if (curskill != null)
            {
//                v62 = curskill.m_pSkillBase.var[0].value;
//                this.m_nUnitExpertLevel = GameRule.GetItemLevelLimit((*&v62 / 10000.0));
            }

            List<int> ref_list = new List<int>();
            for(int i = 0; i < 24; ++i)
            {
                curitem = this.m_anWear[i];
                if (curitem != null)
                {
                    ItemBase.ItemWearType iwt = (ItemBase.ItemWearType)i;
                    if (this.TranslateWearPosition(ref iwt, curitem, ref ref_list))
                    {
                        float fItemRatio = 1.0f;

                        if (curitem.GetLevelLimit() > this.GetLevel() && curitem.GetLevelLimit() <= this.m_nUnitExpertLevel)
                            fItemRatio = 0.40000001f;
                        ItemBase ib = curitem.m_pItemBase;

                        for(int ol = 0; ol < ItemBase.MAX_OPTION_NUMBER; ++ol)
                        {
                            if (ib.nBaseType[ol] != 0)
                            {
                                this.onItemWearEffect(curitem, true, ib.nBaseType[ol],ib.fBaseVar1[ol],ib.fBaseVar2[ol],fItemRatio);
                            }
                        }

                        for(int ol = 0; ol < ItemBase.MAX_OPTION_NUMBER; ++ol)
                        {
                            if (ib.nOptType[ol] != 0)
                            {
                                this.onItemWearEffect(curitem, false, ib.nOptType[ol],ib.fOptVar1[ol],ib.fOptVar2[ol],fItemRatio);
                            }
                        }

                        float fAddPoint = 0.0f;
                        float fTotalPoints = 0.0f;
                        for(int ol = 0; ol < 2; ++ol)
                        {
                            if (ib.nEnhanceID[ol] != 0)
                            {
                                int curEnhance = curitem.m_Instance.nEnhance;
                                int realEnhance = curEnhance;

                                if (realEnhance >= 1 )
                                {
                                    fTotalPoints = ib.fEnhanceVar[0,ol] * (float)curEnhance;

                                    if (realEnhance > 4 )
                                    {
                                        fTotalPoints += (ib.fEnhanceVar[1,ol] * (float)(realEnhance-4));
                                    }
                                    if (realEnhance > 8 )
                                    {
                                        fTotalPoints += (ib.fEnhanceVar[2,ol] * (float)(realEnhance-8));
                                    }
                                    if (realEnhance > 12 )
                                    {
                                        fTotalPoints += (ib.fEnhanceVar[3,ol] * (float)(realEnhance-12));
                                    }
                                    this.onItemWearEffect(curitem, false, ib.nEnhanceID[ol],fTotalPoints,fTotalPoints,fItemRatio);
                                }
                            }
                        }

/*
                        v28 = curitem.m_pItemBase.nSocketCount;
                        if (curitem.m_pItemBase.nSocketCount > 0 )
                        {
                            v67 = 300;
                            fAddPoint = curitem.m_pItemBase.nSocketCount;
                            do
                            {
                                if ( *(&(*v4)->baseclass_0.baseclass_0.baseclass_0.vfptr + v67) )
                                {
                                    v61 = *(&(*v4)->baseclass_0.baseclass_0.baseclass_0.vfptr + v67);
                                    v29 = StructItem::GetItemBase(v61);
                                    v30 = v1->baseclass_0.baseclass_0.baseclass_0.vfptr;
                                    v62._Myptr = v29;
                                    if ( v30[3].IsDeleteable(v1) >= v29->baseclass_0.nMinLevel )
                                    {
                                        if ( v1->baseclass_0.baseclass_0.baseclass_0.vfptr[3].IsDeleteable(v1) <= v29->baseclass_0.nMaxLevel
                                          && (*v4)->m_Instance.nCurrentEndurance )
                                        {
                                            v31 = v29->baseclass_0.nBaseType;
                                            v64 = v29->baseclass_0.nBaseType;
                                            v32 = v29->baseclass_0.fBaseVar1;
                                            base = 4;
                                            do
                                            {
                                                if ( *v31 )
                                                {
                                                    v33 = *(v32 + 32);
                                                    v61 = fItemRatio;
                                                    j = *(v32 + 36);
                                                    (v1->baseclass_0.baseclass_0.baseclass_0.vfptr[17].IsDeleteable)(
                                                        v1,
                                                        *v4,
                                                        1,
                                                        *v31,
                                                        *v32,
                                                        *(v32 + 4),
                                                        v33,
                                                        j,
                                                        fItemRatio);
                                                    v31 = v64;
                                                }
                                                v32 += 8;
                                                v31 += 2;
                                                v13 = base == 1;
                                                base = base - 1;
                                                v64 = v31;
                                            }
                                            while ( !v13 );
                                            v34 = (v62._Myptr + 46);
                                            v64 = (v62._Myptr + 46);
                                            v35 = (v62._Myptr + 48);
                                            base = 4;
                                            do
                                            {
                                                if ( *v34 )
                                                {
                                                    v36 = *(v35 + 32);
                                                    v61 = fItemRatio;
                                                    j = *(v35 + 36);
                                                    (v1->baseclass_0.baseclass_0.baseclass_0.vfptr[17].IsDeleteable)(
                                                        v1,
                                                        *v4,
                                                        0,
                                                        *v34,
                                                        *v35,
                                                        *(v35 + 4),
                                                        v36,
                                                        j,
                                                        fItemRatio);
                                                    v34 = v64;
                                                }
                                                v35 += 8;
                                                v34 += 2;
                                                v13 = base == 1;
                                                base = base - 1;
                                                v64 = v34;
                                            }
                                            while ( !v13 );
                                        }
                                    }
                                }
                                v67 += 2;
                                --fAddPoint;
                            }
                            while ( *&fAddPoint != 0.0 );
                        }
                    
 */ 
                    }
                }

            }

/*
            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                &thisa,
                v1->m_vSetItemEffect._Myfirst,
                &v1->m_vSetItemEffect.baseclass_0.___u0.baseclass_0);
            v62 = thisa;
            v37 = v1->m_vSetItemEffect._Mylast;
            v61 = &v1->m_vSetItemEffect;
            for ( j = v37; ; j = v1->m_vSetItemEffect._Mylast )
            {
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &thisa,
                    j,
                    v61);
                if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(&v62, &thisa) )
                    break;
                v38 = 0;
                fItemRatio = 12;
                do
                {
                    v39 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62);
                    if ( *(fItemRatio + LODWORD(v39->end.x)) )
                    {
                        *&v61 = 1.0;
                        v40 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62)->end.x;
                        j = v41;
                        v42 = LODWORD(v40) + v38 + 52;
                        v43 = *v42;
                        j = *(v42 + 4);
                        v44 = v38
                            + LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62)->end.x)
                            + 20;
                        v45 = *v44;
                        v46 = *(v44 + 4);
                        v47 = &v1->baseclass_0.baseclass_0.baseclass_0.vfptr[17].IsDeleteable;
                        v48 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62);
                        (*v47)(v1, 0, 1, *(LODWORD(v48->end.x) + fItemRatio), v45, v46, v43, j, v61);
                    }
                    fItemRatio += 2;
                    v38 += 8;
                }
                while ( fItemRatio < 20 );
                v49 = 0;
                fItemRatio = 84;
                do
                {
                    v50 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62);
                    if ( *(fItemRatio + LODWORD(v50->end.x)) )
                    {
                        *&v61 = 1.0;
                        v51 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62)->end.x;
                        j = v52;
                        v53 = LODWORD(v51) + v49 + 124;
                        v54 = *v53;
                        j = *(v53 + 4);
                        v55 = v49
                            + LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62)->end.x)
                            + 92;
                        v56 = *v55;
                        v57 = *(v55 + 4);
                        v58 = &v1->baseclass_0.baseclass_0.baseclass_0.vfptr[17].IsDeleteable;
                        v59 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&v62);
                        (*v58)(v1, 0, 0, *(LODWORD(v59->end.x) + fItemRatio), v56, v57, v54, j, v61);
                    }
                    fItemRatio += 2;
                    v49 += 8;
                }
                while ( fItemRatio < 92 );
                std::_Vector_const_iterator<AutoAuctionInfo___std::allocator<AutoAuctionInfo__>>::operator__(&v62);
                v61 = &v1->m_vSetItemEffect;
            }
*/
        }

        protected virtual void applyPassiveSkillEffect(Skill skill)
        {
// Data           :   ebp Relative, [0000007C], Param, Type: struct StructSkill *, pSkill
// Data           :   ebp Relative, [0000007C], Local, Type: int, nAP
// Data           :   ebp Relative, [00000060], Local, Type: int, nMD
// Data           :   ebp Relative, [0000007C], Local, Type: int, nAP
// Data           :   ebp Relative, [00000050], Local, Type: int, nDefence
// Data           :   ebp Relative, [00000058], Local, Type: int, nMP
// Data           :   ebp Relative, [00000060], Local, Type: int, nElemental
// Data           :   ebp Relative, [00000054], Local, Type: class c_fixed<10000>, fCoolTime
// Data           :   ebp Relative, [0000007C], Local, Type: int, nCreatureType
// Data           :   ebp Relative, [0000005C], Local, Type: class c_fixed<10000>, fDamage
// Data           :   ebp Relative, [0000006C], Local, Type: class c_fixed<10000>, fAvoid
// Data           :   ebp Relative, [0000006C], Local, Type: class c_fixed<10000>, fMPHealRatio
// Data           :   ebp Relative, [0000005C], Local, Type: class c_fixed<10000>, fHPHealRatio
// Data           :   ebp Relative, [0000005C], Local, Type: class c_fixed<10000>, fHPHealRatioByItem
// Data           :   ebp Relative, [0000006C], Local, Type: class c_fixed<10000>, fMPHealRatioByItem
// Data           :   ebp Relative, [00000064], Local, Type: class c_fixed<10000>, fMPHealRatioByRest
// Data           :   ebp Relative, [0000006C], Local, Type: class c_fixed<10000>, fHPHealRatioByRest
// Data           :   ebp Relative, [0000006C], Local, Type: class c_fixed<10000>, fMagicPoint
// Data           :   ebp Relative, [00000064], Local, Type: class c_fixed<10000>, fAccuracy
// Data           :   ebp Relative, [0000005C], Local, Type: class c_fixed<10000>, fAttackPoint
// Data           :   ebp Relative, [00000054], Local, Type: class c_fixed<10000>, fAttackSpeed
// 
            // 0x118 = m_var[0];
            // 0x120 = m_var[1];
            // 0x128 = m_var[2];
            // 0x130 = m_var[3];
            float atk = 0;

            switch(skill.m_SkillBase.effect_type)
            {
                case (int) SkillBase.EffectType.WeaponMastery: // 10001
                    Item weapon = this.GetWornItem(ItemBase.ItemWearType.WearWeapon);
                    if(weapon == null)
                        return;

                    if(skill.m_SkillBase.uid == (int)SkillBase.SkillId.AdvWeaponExpert)
                        if(weapon.GetItemRank() < 2)
                            return;

                    atk = (skill.m_SkillBase.m_var[0] + (skill.m_SkillBase.m_var[1] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel)));
                    this.m_Attribute.nAttackPointRight += atk;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        this.m_Attribute.nAttackPointLeft += atk;

                    this.m_Attribute.nAttackSpeed += (skill.m_SkillBase.m_var[2] + (skill.m_SkillBase.m_var[3] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel)));

                    //(int)(skill.m_SkillBase.m_var[0] + (skill.m_SkillBase.m_var[1] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel)));
                    break;

                case (int)SkillBase.EffectType.IncreaseBaseAttribute: // 10008
                    atk = (skill.m_SkillBase.m_var[0] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    this.m_Attribute.nAttackPointRight += atk;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        this.m_Attribute.nAttackPointLeft += atk;
                    
                    this.m_Attribute.nDefence += (skill.m_SkillBase.m_var[1] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    this.m_Attribute.nMagicPoint += (skill.m_SkillBase.m_var[2] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    this.m_Attribute.nMagicDefence += (skill.m_SkillBase.m_var[3] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    
                    atk = (skill.m_SkillBase.m_var[6] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    this.m_Attribute.nAccuracyRight += atk;
                    if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                        this.m_Attribute.nAttackPointLeft += atk;
                    this.m_Attribute.nMagicAccuracy += (skill.m_SkillBase.m_var[7] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel));
                    break;

                case (int)SkillBase.EffectType.IncreaseHPMP: // 10021
                    this.m_nMaxHP += (int)(skill.m_SkillBase.m_var[0] + (skill.m_SkillBase.m_var[1] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel)));
                    this.m_nMaxMP += (int)(skill.m_SkillBase.m_var[2] + (skill.m_SkillBase.m_var[3] * (skill.m_nSkillLevelAdd + skill.m_nSkillLevel)));
                    break;

                default:
                    //Globals.Log.Error("Unknown Skill Effect Type in Creature.applyPassiveSkillEffect: {0} Skill: {1} ({2})",skill.m_SkillBase.effect_type,GameContent.GetString(skill.m_SkillBase.name_id),skill.m_SkillBase.uid);
                    break;
            }

// .text:0042CA96                 push    ebp
// .text:0042CA97                 lea     ebp, [esp-74h]
// .text:0042CA9B                 sub     esp, 370h
// .text:0042CAA1                 push    ebx
// .text:0042CAA2                 push    esi
// .text:0042CAA3                 mov     esi, skill
// .text:0042CAA6                 mov     eax, skill.m_SkillBase
// .text:0042CAA9                 push    edi
// .text:0042CAAA                 mov     edi, this
// .text:0042CAAC                 movsx   this, skill.m_SkillBase.effect_type
// .text:0042CAB3                 mov     edx, 271Bh (10011)
// .text:0042CAB8                 cmp     this, edx
// .text:0042CABA                 jg      loc_42DE65 > 10011
// .text:0042CAC0                 jz      loc_42E57B = 10011
// .text:0042CAC6                 add     edx, 0FFFFFFFAh 10005
// .text:0042CAC9                 cmp     this, edx
// .text:0042CACB                 jg      loc_42D206 > 10005
// .text:0042CAD1                 jz      loc_42D150 = 10005
// .text:0042CAD7                 xor     ebx, ebx
// .text:0042CAD9                 sub     this, ebx
// .text:0042CADB                 jz      loc_42D068 == 0
// .text:0042CAE1                 sub     this, 10001 effect_type - 10001
// .text:0042CAE7                 jz      loc_42CE1B = 10001
// .text:0042CAED                 dec     this 10000
// .text:0042CAEE                 jz      loc_42CC18 = 10000
// .text:0042CAF4                 dec     this 9999
// .text:0042CAF5                 jz      short loc_42CB5E = 9999
// .text:0042CAF7                 dec     this 9998
// .text:0042CAF8                 jnz     loc_42EB60 != 9998
// .text:0042CAFE                 mov     eax, [esi+14h] = 9998
// .text:0042CB01                 add     eax, [esi+10h]
// .text:0042CB04                 mov     esi, [esi+1Ch]
// .text:0042CB07                 mov     this, [esi+120h]
// .text:0042CB0D                 mov     ebx, [esi+118h]
// .text:0042CB13                 mov     dword ptr [ebp+74h+fMagicPoint.value], this
// .text:0042CB16                 mov     this, [esi+124h]
// .text:0042CB1C                 mov     esi, [esi+11Ch]
// .text:0042CB22                 push    eax             ; n
// .text:0042CB23                 lea     eax, [ebp+74h+result]
// .text:0042CB29                 mov     dword ptr [ebp+74h+fMagicPoint.value+4], this
// .text:0042CB2C                 push    eax             ; result
// .text:0042CB2D                 lea     this, [ebp+74h+fMagicPoint] ; this
// .text:0042CB30                 call    ??$?DH@?$c_fixed@$0CHBA@@@QBE?AV0@H@Z ; c_fixed<10000>::operator*<int>(int)
// .text:0042CB35                 add     ebx, [eax]
// .text:0042CB37                 adc     esi, [eax+4]
// .text:0042CB3A                 mov     dword ptr [ebp+74h+fMagicPoint.value], ebx
// .text:0042CB3D                 mov     dword ptr [ebp+74h+fMagicPoint.value+4], esi
// .text:0042CB40                 fild    [ebp+74h+fMagicPoint.value]
// .text:0042CB43                 fdiv    ds:__real@40c3880000000000
// .text:0042CB49                 call    __ftol2_sse
// .text:0042CB4E                 imul    ax, 64h
// .text:0042CB52                 add     [edi+1FCh], ax
// .text:0042CB59                 jmp     loc_42EB60

// .text:0042D206 loc_42D206:                             ; CODE XREF: StructCreature::applyPassiveSkillEffect(StructSkill *)+35j
// .text:0042D206                 sub     this, 10006
// .text:0042D20C                 jz      loc_42DDC9 == 10006
// .text:0042D212                 dec     this 10005
// .text:0042D213                 jz      loc_42DBED == 10005
// .text:0042D219                 dec     this 10004
// .text:0042D21A                 jz      loc_42D76A == 10004
// .text:0042D220                 dec     this = 10003
// .text:0042D221                 jz      loc_42D49C == 10003
// .text:0042D227                 dec     this = 10002
// .text:0042D228                 jnz     loc_42EB60 


        }

        protected virtual void applyPassiveSkillEffect()
        {
            foreach (Skill s in this.m_vPassiveSkillList)
            {
                bool r = s.m_SkillBase.vf_shield_only == 0 ? s.m_SkillBase.IsUseableWeapon(this.GetWeaponClass()) : this.IsWearShield();
                if (s.m_SkillBase.vf_is_not_need_weapon != 0 || r)
                    this.applyPassiveSkillEffect(s);
            }
        }

        protected virtual void applyPassiveSkillAmplifyEffect(Skill skill)
        {

        }

        protected virtual void applyPassiveSkillAmplifyEffect()
        {

        }

        protected void applyStateEffect()
        {
            int[] nLevel = new int[3];                          // -96  -60h
            int[] nOriginalLevel = new int[3];                  // -84  -54h
            List<RappelzPair<int,int>> vDecreaseList = new List<RappelzPair<int,int>>();    // -112 -70h

            if (this.m_vStateList.Count > 0)
            {
                foreach (State s in this.m_vStateList)
                {
                    if (s.GetEffectType() == 84)
                    {
                        int dv = (int)(s.GetValue(0) + (s.GetValue(1) * s.GetLevel()));
                        for(int i = 2; i < 11; ++i)
                        {
                            vDecreaseList.Add(new RappelzPair<int,int>((int)s.GetValue(i),dv));
                        }
                    }
                }

                foreach (State s in this.m_vStateList)
                {
                    nOriginalLevel[0] = s.m_nLevel[0];
                    nOriginalLevel[1] = s.m_nLevel[1];
                    nOriginalLevel[2] = s.m_nLevel[2];

/*
                    foreach (RappelzPair<int,int> rp in vDecreaseList)
                    {
                        if (rp.First == (int)s.m_nCode)
                        {
                            nLevel[0] = 0;
                            nLevel[1] = 0;
                            nLevel[2] = 0;
                            for(int i = 2; i >= 0; --i)
                            {
                                int dv = nOriginalLevel[i] - rp.Second;

                                nLevel[i] = dv;
                                if (dv < 0)
                                {
                                    v21 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 - 32));
                                    nLevel[i] = 0;
                                    sLODWORD(v21->end.y) = -dv;
                                }
                            }

                            s.m_nLevel[0] =  nLevel[0];
                            s.m_nLevel[1] =  nLevel[1];
                            s.m_nLevel[2] =  nLevel[2];
                            break;
                        }
                    }

*/
                    if (s.GetLevel() != 0)
                    {
                        this.applyState(s);
                    }
                    s.m_nLevel[0] = nOriginalLevel[0];
                    s.m_nLevel[1] = nOriginalLevel[1];
                    s.m_nLevel[2] = nOriginalLevel[2];
                }
            }
        }

        protected void applyStateAmplifyEffect()
        {
            int[] nLevel = new int[3];                          // -96  -60h
            int[] nOriginalLevel = new int[3];                  // -84  -54h
            List<RappelzPair<int,int>> vDecreaseList = new List<RappelzPair<int,int>>();    // -112 -70h

            if (this.m_vStateList.Count > 0)
            {
                foreach (State s in this.m_vStateList)
                {
                    if (s.GetEffectType() == 84)
                    {
                        int dv = (int)(s.GetValue(0) + (s.GetValue(1) * s.GetLevel()));
                        for(int i = 2; i < 11; ++i)
                        {
                            vDecreaseList.Add(new RappelzPair<int,int>((int)s.GetValue(i),dv));
                        }
                    }
                }

                foreach (State s in this.m_vStateList)
                {
                    nOriginalLevel[0] = s.m_nLevel[0];
                    nOriginalLevel[1] = s.m_nLevel[1];
                    nOriginalLevel[2] = s.m_nLevel[2];

/*
                    foreach (RappelzPair<int,int> rp in vDecreaseList)
                    {
                        if (rp.First == (int)s.m_nCode)
                        {
                            nLevel[0] = 0;
                            nLevel[1] = 0;
                            nLevel[2] = 0;
                            for(int i = 2; i >= 0; --i)
                            {
                                int dv = nOriginalLevel[i] - rp.Second;

                                nLevel[i] = dv;
                                if (dv < 0)
                                {
                                    v21 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v1 - 32));
                                    nLevel[i] = 0;
                                    sLODWORD(v21->end.y) = -dv;
                                }
                            }

                            s.m_nLevel[0] =  nLevel[0];
                            s.m_nLevel[1] =  nLevel[1];
                            s.m_nLevel[2] =  nLevel[2];
                            break;
                        }
                    }

*/
                    if (s.GetLevel() != 0)
                    {
                        this.applyStateAmplify(s);
                    }
                    s.m_nLevel[0] = nOriginalLevel[0];
                    s.m_nLevel[1] = nOriginalLevel[1];
                    s.m_nLevel[2] = nOriginalLevel[2];
                }
            }

        }

        protected void applyDoubleWeaponEffect()
        {
            float fAddPerLevel;     // -16  -10
            Skill skill = null;

            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
            {
                Item pSlot0 = this.GetWornItem(ItemBase.ItemWearType.WearWeapon);
                Item pSlot1 = this.GetWornItem(ItemBase.ItemWearType.WearShield);
                if(pSlot0 != null || pSlot1 != null)
                {
                    int skillLevel = 1;
                    if (pSlot1.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandSword
                        && pSlot0.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandSword)
                    {
                        skill = this.GetCurrentPassiveSkill((int)SkillBase.SkillId.DualSwordExpert);
                    }
                    else if (pSlot1.m_pItemBase.nClass == ItemBase.ItemClass.ClassDagger
                        && pSlot0.m_pItemBase.nClass == ItemBase.ItemClass.ClassDagger)
                    {
                        skill = this.GetCurrentPassiveSkill((int)SkillBase.SkillId.TwinBladeExpert);
                    }
                    else if (pSlot1.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandAxe
                        && pSlot0.m_pItemBase.nClass == ItemBase.ItemClass.ClassOneHandAxe)
                    {
                        skill = this.GetCurrentPassiveSkill((int)SkillBase.SkillId.TwinAxeExpert);
                    }
                    if(skill != null)
                        skillLevel = skill.m_nSkillLevel + skill.m_nSkillLevelAdd;


                    fAddPerLevel = 0;
                    this.m_nDoubleWeaponMasteryLevel = skillLevel;
                    fAddPerLevel = 0.5f;
                    this.m_Attribute.nAttackSpeedRight *= (0.75f+((float)skillLevel*0.005f));
                    this.m_Attribute.nAttackSpeedLeft *= (0.75f+((float)skillLevel*0.005f));
                    this.m_Attribute.nAttackSpeed = (this.m_Attribute.nAttackSpeedLeft+this.m_Attribute.nAttackSpeedRight) * 0.5f;
                    this.m_AttributeByState.nAttackSpeedRight *= (0.75f+((float)skillLevel*0.005f));
                    this.m_AttributeByState.nAttackSpeedLeft *= (0.75f+((float)skillLevel*0.005f));
                    this.m_AttributeByState.nAttackSpeed = (this.m_AttributeByState.nAttackSpeedLeft+this.m_AttributeByState.nAttackSpeedRight) * 0.5f;

                    this.m_Attribute.nAccuracyLeft *= (0.89f + ((float)skillLevel * 0.01f));
                    this.m_Attribute.nAccuracyRight *= (0.89f + ((float)skillLevel * 0.01f));
                    this.m_AttributeByState.nAccuracyLeft *= (0.89f + ((float)skillLevel * 0.01f));
                    this.m_AttributeByState.nAccuracyRight *= (0.89f + ((float)skillLevel * 0.01f));

                    this.m_Attribute.nAttackPointRight *= (0.9f+((float)skillLevel*0.01f));
                    this.m_Attribute.nAttackPointLeft *= (0.44f+((float)skillLevel*0.02f));
                    this.m_nAttackPointRightWithoutWeapon *= (0.9f + ((float)skillLevel * 0.01f));
                    this.m_nAttackPointRightWithoutWeapon *= (0.44f + ((float)skillLevel * 0.02f));
                    this.m_AttributeByState.nAttackPointRight *= (0.9f + ((float)skillLevel * 0.01f));
                    this.m_AttributeByState.nAttackPointLeft *= (0.44f + ((float)skillLevel * 0.02f));
                    return;
                }
            }
            this.m_Attribute.nAttackSpeed = this.m_Attribute.nAttackSpeedRight;
            this.m_AttributeByState.nAttackSpeed = this.m_AttributeByState.nAttackSpeedRight;
        }


        protected virtual void onItemWearEffect(Item pItem, bool bIsBaseVar, int type, float var1, float var2, float fRatio)
        {
            float result;
            float item_var_penalty;

            Player p = null;
            if(this.IsPlayer())
                p = this as Player;

            if (type == 14 )
                item_var_penalty = var1;
            else
                item_var_penalty = var1*fRatio;

            if (type != 14 )
            {
                if (pItem != null && bIsBaseVar)
                {
                    item_var_penalty += (float)(var2*(float)pItem.m_Instance.nLevel);
                    result = var1;
                    item_var_penalty = GameRule.GetItemValue(item_var_penalty, (int)var1, this.GetLevel(), pItem.GetItemRank(), pItem.m_Instance.nLevel);
                }
                this.m_fItemMod = item_var_penalty;
            }

            if (type > 96 )
            {
                int t1 = type - 97;
                if (t1 != 0)
                {
                    int t2 = t1 - 1;
                    if (t2 != 0)
                    {
                        if (t2 == 1)
                            this.ampParameter2((uint)var1, var2);
                    }
                    else
                    {
                        this.ampParameter((uint)var1, var2,false);
                    }
                }
                else
                {
                    this.incParameter2((uint) var1, var2);
                }
            }
            else
            {
                if (type == 96 )
                {
                    this.incParameter((uint) var1, (int)var2, false);
                }
                else
                {
                    switch (type)
                    {
                        case 12:
                            this.m_Attribute.nMagicPoint += item_var_penalty;
                            return;

                        case 11:
                            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) == 0)
                            {
                                this.m_Attribute.nAttackPointRight += item_var_penalty;
                            }
                            else if (pItem == null || pItem.m_pItemBase.nGroup != 1)
                            {
                                this.m_Attribute.nAttackPointLeft += item_var_penalty;
                                this.m_Attribute.nAttackPointRight += item_var_penalty;
                            }
                            else if (pItem.m_Instance.nWearInfo != ItemBase.ItemWearType.WearShield)
                            {
                                this.m_Attribute.nAttackPointRight += item_var_penalty;
                            }
                            else
                            {
                                this.m_Attribute.nAttackPointLeft += item_var_penalty;
                            }
                            return;

                        case 21:
                            this.m_Attribute.nBlockDefence += item_var_penalty;
                            return;

                        case 15:
                            this.m_Attribute.nDefence += item_var_penalty;
                            return;

                        case 13:
                            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) == 0)
                            {
                                this.m_Attribute.nAccuracyRight += item_var_penalty;
                            }
                            else if (pItem == null || pItem.m_pItemBase.nGroup != 1)
                            {
                                this.m_Attribute.nAccuracyLeft += item_var_penalty;
                                this.m_Attribute.nAccuracyRight += item_var_penalty;
                            }
                            else if (pItem.m_Instance.nWearInfo != ItemBase.ItemWearType.WearShield)
                            {
                                this.m_Attribute.nAccuracyRight += item_var_penalty;
                            }
                            else
                            {
                                this.m_Attribute.nAccuracyLeft += item_var_penalty;
                            }
                            return;

                        case 14:
                            if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) == 0)
                            {
                                this.m_Attribute.nAttackSpeedRight += item_var_penalty;
                            }
                            else if (pItem == null || pItem.m_pItemBase.nGroup != 1)
                            {
                                this.m_Attribute.nAttackSpeedRight += item_var_penalty;
                                this.m_Attribute.nAttackSpeedLeft += item_var_penalty;
                            }
                            else if ( pItem.m_Instance.nWearInfo != ItemBase.ItemWearType.WearShield)
                            {
                                this.m_Attribute.nAttackSpeedRight += item_var_penalty;
                            }
                            else
                            {
                                this.m_Attribute.nAttackSpeedLeft += item_var_penalty;
                            }
                            return;

                        case 16:
                            this.m_Attribute.nMagicDefence += item_var_penalty;
                            return;

                        case 17:
                            this.m_Attribute.nAvoid += item_var_penalty;
                            return;
                        
                        case 18:
                            if ((this.m_StatusFlag & StatusFlags.MoveSpeedFixed) == 0 && (p == null || p.m_nRidingStateUid == 0))
                                this.m_Attribute.nMoveSpeed += item_var_penalty;
                            return;
                        case 19:
                            this.m_Attribute.nBlockChance += item_var_penalty;
                            return;
                        case 20:
                            this.m_Attribute.nMaxWeight += item_var_penalty;
                            return;

                        case 22:
                            this.m_Attribute.nCastingSpeed += item_var_penalty;
                            return;
                        case 23:
                            this.m_Attribute.nMagicAccuracy += item_var_penalty;
                            break;
                        case 24:
                            this.m_Attribute.nMagicAvoid += item_var_penalty;
                            break;
                        case 25:
                            this.m_Attribute.nCoolTimeSpeed += item_var_penalty;
                            break;
                        case 30:
                            this.m_nMaxHP += (short)item_var_penalty;
                            break;
                        case 31:
                            this.m_nMaxMP += (short)item_var_penalty;
                            break;
                        case 33:
                            this.m_Attribute.nMPRegenPoint += item_var_penalty;
                            break;
                        case 34:
                            this.m_fBowInterval = var1;
                            break;
                        default:
                            return;
                    }
                }
            }

        }

// Function       :   protected const bool isFirstAttack()
// Function       :   protected const bool isAttackStarted()
// Function       :   protected const bool isMortal()
// Function       :   protected const bool isMoveSpeedFixed()
// Function       :   protected const bool isFearMoving()
// Function       :   protected const bool isHPRegenStopped()
// Function       :   protected const bool isMPRegenStopped()
// Function       :   protected const bool isNeedToCalculateStat()
        protected virtual void onBeforeCalculateStat()
        {

        }

        protected virtual void onAfterApplyStat()
        {

        }

        protected virtual void onApplyStat()
        {

        }

        protected virtual void onAfterCalculateAttributeByStat()
        {

        }

        protected virtual void onApplyAttributeAdjustment()
        {

        }

        protected virtual void onModifyStatAndAttribute()
        {

        }

        protected virtual void onCompleteCalculateStat()
        {

        }

        protected virtual void onAfterAddState(State state)
        {
            this.procMoveSpeedChange();
        }

        protected virtual void onAfterRemoveState(State state)
        {
            this.procMoveSpeedChange();
        }

        protected void procMoveSpeedChange()
        {
            List<ArPosition> vMovePos; // -44

            if (this.mv.bIsMoving && this.bIsInWorld)
            {
                uint ct = Globals.GetArTime();
                ArPosition pos = this.GetCurrentPosition(ct);
                if (this.IsMovable())
                {
                    if (this.mv.speed != this.GetMoveSpeed() / 7)
                    {
                        vMovePos = new List<ArPosition>();

                        foreach (ArMoveVector.MoveInfo mi in this.mv.ends)
                        {
                            vMovePos.Add(mi.end);
                        }
                        RappelzServer.Instance.SetMultipleMove(this,pos,vMovePos,(sbyte)(this.GetMoveSpeed() / 7),true,ct,true);
                    }
                }
                else
                {
                    RappelzServer.Instance.SetMove(this, pos, pos, 0, true, ct, true);
                }
            }
        }

        protected void finalizeStat()
        {
            if (m_Stat.strength < 0)
                m_Stat.strength = 0;
            if (m_Stat.vital < 0)
                m_Stat.vital = 0;
            if (m_Stat.dexterity < 0)
                m_Stat.dexterity = 0;
            if (m_Stat.agility < 0)
                m_Stat.agility = 0;
            if (m_Stat.intelligence < 0)
                m_Stat.intelligence = 0;
            if (m_Stat.mentality < 0)
                m_Stat.mentality = 0;
            if (m_Stat.luck < 0)
                m_Stat.luck = 0;
        }

        protected virtual void onUpdateState(State state, bool bIsExpire)
        {
            Messages.BroadcastStateMessage(this, state, bIsExpire);
        }

        protected virtual bool onProcAura(Skill skill, int nRequestedLevel)
        {
            skill.SetRequestedSkillLevel(nRequestedLevel);
            bool res = skill.ProcAura();
            skill.SetRequestedSkillLevel(0);
            return res;
        }

        protected virtual void onCantAttack(uint target, uint t)
        {

        }

        protected virtual void onDead(Creature pFrom, bool decreaseEXPOnDead)
        {
            ArPosition pos;

            if (this.m_pCastSkill != null)
                this.CancelSkill();
            if (this.mv.bIsMoving && this.bIsInWorld)
            {
                pos = this.GetCurrentPosition(this.m_nDeadTime);
                RappelzServer.Instance.SetMove(this, pos, pos, 0, true, Globals.GetArTime(), true);
                if (this.IsPlayer())
                {
                    Player p = this as Player;
                    Summon ride = p.GetRideObject();
                    if (ride != null)
                    {
                        RappelzServer.Instance.SetMove(p, pos,pos, 0, true, Globals.GetArTime(), true);
                    }
                }
            }
            if (this.m_hEnemy != 0)
                this.EndAttack();
            this.RemoveAllAura();
            this.RemoveAllHate();
            this.removeStateByDead();
        }

// Function       :   protected void StructCreature::onMPChange()
        protected virtual void onJobLevelUp()
        {

        }

        protected virtual void onExpChange()
        {

        }

        protected virtual void onMaxHavocChange()
        {

        }

        protected virtual void onHavocChange()
        {

        }

        protected virtual void onEnergyChange()
        {

        }

        protected virtual void onRegisterSkill(int skill_uid, int skill_id, int prev_skill_level, int skill_level)
        {

        }

// Function       :   protected void StructCreature::onStatChange()
// Function       :   protected void StructCreature::onAttributeChange()
// Function       :   protected int StructCreature::getJPAfterSkillReset()
// Function       :   protected void StructCreature::onBeforeResetSkill()
// Function       :   protected void StructCreature::onAfterResetSkill()

        protected virtual void regenHPMP(uint t)
        {
            float prev_mp;
            int prev_hp;
            float pt;

            uint et = t - this.m_nLastUpdateTime;
            if (et >= 300)
            {
                float etf = (float) et / 6000.0f;
                //prev_mp = et;

                if (this.m_nHP != 0)
                {
                    prev_mp = this.m_fMP;
                    prev_hp = this.m_nHP;
                    if (!this.IsMagicalImmune())
                    {
// 
//                         if (this.m_Attribute.nHPAdd != 0)
//                         {
//                             pt = (double)this.m_Attribute.nHPAdd * etf;
//                             if (pt < 1.0 )
//                                 pt += 1.0;
//                             if (pt != 0.0)
//                                 this.Heal((int)pt);
//                         }
// 
//                         if (this.m_Attribute.nHPAddByItem != 0)
//                         {
//                             pt = (double)this.m_Attribute.nHPAddByItem * etf;
//                             if (pt < 1.0 )
//                                 pt += 1.0;
//                             if (pt != 0.0)
//                                 this.HealByItem((int)pt);
//                         }
// 
//                         if (this.m_Attribute.nMPAdd != 0)
//                         {
//                             pt = (double)this.m_Attribute.nMPAdd * etf;
//                             if (pt < 1.0)
//                                 pt += 1.0;
//                             if (pt != 0.0)
//                                 this.MPHeal((int)pt);
//                         }
// 
//                         if (this.m_Attribute.nMPAddByItem != 0)
//                         {
//                             pt = (double)this.m_Attribute.nMPAddByItem * etf;
//                             if (pt < 1.0 )
//                                 pt += 1.0;
//                             if (pt != 0.0)
//                                 this.MPHealByItem((int)pt);
//                         }
                    }
                    if ((this.m_StatusFlag & StatusFlags.HPRegenStopped) == 0)
                    {
                        pt = this.m_nMaxHP * this.m_Attribute.nHPRegenPercentage;
                        pt = pt * 0.01f * etf;// + 0.0;
                        pt = pt + this.m_Attribute.nHPRegenPoint * etf;
                        if (this.IsSitDown())
                        {
                            pt *= this.m_fHealRatioByRest;
                            pt += (float)this.m_nAdditionalHealByRest;
                        }
                        if (pt < 1.0f)
                            pt = 1.0f;
                        pt *= this.m_fHPRegenMod;
                        if (pt != 0.0)
                            this.AddHP((int)pt);
                        int pti = (int) pt;
                        this.m_nHPDecPart = (int)((pt - (double)pti) * 100.0 + (double)this.m_nHPDecPart);
                        int part = this.m_nHPDecPart / 100;
                        if (part != 0)
                        {
                            this.AddHP(part);
                            this.m_nHPDecPart = this.m_nHPDecPart % 100;
                        }
                    }
                    if ((this.m_StatusFlag & StatusFlags.MPRegenStopped) == 0)
                    {
                        pt = this.m_nMaxMP * this.m_Attribute.nMPRegenPercentage;
                        pt = pt * 0.01f * etf;// +0.0;
                        pt = pt + (float)this.m_Attribute.nMPRegenPoint * etf;

                        if (this.IsSitDown())
                            pt = this.m_fMPHealRatioByRest * pt;
                        if (pt < 1.0f)
                            pt = 1.0f;
                        pt = this.m_fMPRegenMod * pt;
                        if (pt != 0.0)
                            this.AddMP(pt);
                    }

                    if (prev_hp != this.m_nHP || prev_mp != this.m_fMP)
                    {
                        this.m_fRegenMP += (this.m_fMP - prev_mp);
                        this.m_nRegenHP += this.m_nHP - prev_hp;
                        if (this.m_nMaxHP == this.m_nHP || this.m_nMaxMP == this.m_fMP || 100 * this.m_nRegenHP / this.m_nMaxHP > 3 || 100 * this.m_fRegenMP / this.m_nMaxMP > 3)
                        {
                            PacketOut pak = new PacketOut((ushort)ClientOutPackets.HPMPRegen);
                            if(GameRule.nClientVersion >= 74)
                            {
                                pak.WriteUInt32(this.m_hHandle);
                                pak.WriteInt32((int)this.m_nRegenHP);
                                pak.WriteInt32((int)this.m_fRegenMP);
                                pak.WriteInt32(this.m_nHP);
                                pak.WriteInt32((int)this.m_fMP);
                            }
                            else
                            {
                                pak.WriteUInt32(this.m_hHandle);
                                pak.WriteInt16((short)this.m_nRegenHP);
                                pak.WriteInt16((short)this.m_fRegenMP);
                                pak.WriteInt32(this.m_nHP);
                                pak.WriteInt16((short)this.m_fMP);
                            }

                            this.m_nRegenHP = 0;
                            this.m_fRegenMP = 0;
                            if (this.bIsInWorld)
                            {
                                RappelzServer.Instance.Broadcast((uint)((float)this.mv.x / GameContent.g_nRegionSize), (uint)((float)this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                            }
                            if (this.IsSummon())
                            {
                                Summon s = (Summon) this;
                                Player player = s.m_master;
                                if (player != null)
                                {
                                    if (player.bIsInWorld && (player.m_StatusFlag & StatusFlags.LoginComplete) != 0)
                                    {
                                        if (player.m_nLogoutTime == 0)
                                            player.Connection.SendTCP(pak);
                                    }
                                }
                            }
                        }
                    }
                }
                this.m_nLastUpdateTime = t;
            }
        }

        protected virtual void procStateDamage(uint t)
        {
            List<StateDamage> vDamageList = new List<StateDamage>();

// .text:0043BADC msg             = TS_SC_STATE_RESULT ptr -0E0h
            Damage damage;                                  // -156 -9Ch
// .text:0043BADC itCaster        = StructCreature::iterator ptr -2Ch
// .text:0043BADC t               = dword ptr  4
// .text:0043BADC cit             = StructCreature::iterator ptr  20h
            int damage_mp;                                  // 52   34h
            bool bFinal;                                    // 52   34h
            uint nThisFireTime;                             // 68   44h
            Elemental.Type elem;                            // 76   4Ch
            bool bNeedToProcLightningForceCongestion;       // 83   53h
            int nBaseEffectID;                              // 84   54h
            int nHealMP;                                    // 84   54h
            int nFlag;                                      // 92   5Ch
            int nDamageHP;                                  // 104  68h
            int nDamageMP;                                  // 92   5Ch
// .text:0043BADC nDamageHP       = dword ptr  64h
// .text:0043BADC it              = std::_Vector_iterator<StructState,std::allocator<StructState> > ptr  6Ch
            int nHealHP;                                    // 124  7Ch
            int damage_hp;                                  // 124  7Ch

// Data           :   ebp Relative, [0000007C], Param, Type: unsigned long, t

// Data           :   ebp Relative, [00000064], Local, Type: class std::_Vector_iterator<StateDamage,std::allocator<StateDamage> >, vit
// Data           :   ebp Relative, [0000006C], Local, Type: class std::_Vector_iterator<StructState,std::allocator<StructState> >, it
// Data           :   ebp Relative, [FFFFFFD4], Local, Type: struct StructCreature::iterator, itCaster
// Data           :   ebp Relative, [00000020], Local, Type: struct StructCreature::iterator, cit
// Data           :   ebp Relative, [FFFFFF20], Local, Type: struct TS_SC_STATE_RESULT, msg
// Data           :   ebp Relative, [00000028], Local, Type: class std::_Vector_iterator<StructState,std::allocator<StructState> >, it
// Data           :   ebp Relative, [FFFFFFA8], Local, Type: struct TS_SC_STATE_RESULT, msg
// Data           :   ebp Relative, [00000040], Local, Type: class std::_Vector_iterator<StructState,std::allocator<StructState> >, it
// Data           :   ebp Relative, [FFFFFF84], Local, Type: struct TS_SC_STATE_RESULT, msg
// Data           :   ebp Relative, [00000018], Local, Type: struct StructCreature::iterator, itCaster
            PacketOut pak;

            bNeedToProcLightningForceCongestion = false;

            foreach(State st in this.m_vStateList)
            {
                if (this.IsPlayer() || this.IsSummon())
                {
                    Creature caster = Creature.get(st.m_hCaster[0]) as Creature;
                    if (caster == null)
                    {
                        if (st.m_nCode != State.StateCode.GaiaMembership
                            && st.m_nCode != State.StateCode.Nemesis
                            && st.m_nCode != State.StateCode.NemesisForAuto
                            && st.m_nCode != State.StateCode.FallFromSummon
                            && st.IsHarmful())
                        {
                            st.AddState(State.StateType.Normal, st.m_hCaster[0], (ushort)st.m_nLevel[0], st.m_nStartTime[0], (uint)(t - 1), st.m_nBaseDamage[0], false);
                            this.CalculateStat();
                            this.onUpdateState(st,false);
                            continue;
                        }
                    }
                }

                nThisFireTime = (uint)(st.m_nLastProcessedTime + 100 * GameContent.GetStateInfo((int)st.m_nCode).fire_interval);
                if (nThisFireTime < t)
                {
                    if (nThisFireTime <= st.m_nEndTime[0])
                    {
                        if (st.m_nCode == State.StateCode.LightningForceCongestion)
                            bNeedToProcLightningForceCongestion = true;
                        nBaseEffectID = st.m_info.base_effect_id;
                        if (nBaseEffectID <= 0)
                            continue;

                        nDamageHP = 0;
                        nDamageMP = 0;
                        elem = (Elemental.Type)st.m_info.elemental_type;

                        switch (nBaseEffectID)
                        {
                            case 1:
                            case 2:
                            case 3:
                            case 4:
                            case 11:
                                nDamageHP = (int)((st.m_info.add_damage_per_skl * st.GetLevel())
                                    + (st.m_nBaseDamage[0] * (st.m_info.amplify_base + (st.m_info.amplify_per_skl * st.GetLevel())))
                                    + st.m_info.add_damage_base);
                                break;

                            case 6:
                                nDamageHP = (int)((st.GetValue(0) + (st.GetValue(1) * st.GetLevel())) * this.m_nMaxHP);
                                nDamageMP = (int)((st.GetValue(2) + (st.GetValue(3) * st.GetLevel())) * this.m_nMaxMP);
                                break;

                            case 12:
                                nDamageMP = (int)((st.m_info.add_damage_per_skl * st.GetLevel())
                                    + (st.m_nBaseDamage[0] * (st.m_info.amplify_base + (st.m_info.amplify_per_skl * st.GetLevel())))
                                    + st.m_info.add_damage_base);
                                break;

                            case 21:
                                nDamageHP = (st.m_info.add_damage_base + (st.m_info.add_damage_per_skl * st.GetLevel()));
                                break;

                            case 22:
                                nDamageMP = st.m_info.add_damage_base + (st.m_info.add_damage_per_skl * st.GetLevel());
                                break;

                            case 24:
                                nDamageHP = st.m_info.add_damage_base + (st.m_info.add_damage_per_skl * st.GetLevel());
                                nDamageMP = st.m_info.add_damage_base + (st.m_info.add_damage_per_skl * st.GetLevel());
                                break;

                            case 25:
                                nDamageHP = (int)((st.GetValue(0) + (st.GetValue(1) * st.GetLevel())) * this.m_nMaxHP);
                                nDamageMP = (int)((st.GetValue(3) + (st.GetValue(4) * st.GetLevel())) * this.m_nMaxMP);
                                break;

                        }

                        if (nDamageHP != 0 || nDamageMP != 0)
                        {
                            st.m_nLastProcessedTime = nThisFireTime;

                            StateDamage sd = new StateDamage(st.m_hCaster[0], elem, nBaseEffectID, (int)st.m_nCode, st.GetLevel(), nDamageHP, nDamageMP,
                                nThisFireTime + (100 * GameContent.GetStateInfo((int)st.m_nCode).fire_interval) > st.m_nEndTime[0], st.m_nUID);

                            vDamageList.Add(sd);
                        }
                    }
                }

            }

            if (vDamageList.Count > 0)
            {
                Priority priority;
                if (this.pending_priority == SchedulerObject.Priority.Null)
                    priority = this.priority;
                else
                    priority = this.pending_priority;
                if ((int)priority < 3 )
                {
                    if (this.pending_priority == Priority.Null)
                        priority = this.priority;
                    else
                        priority = this.pending_priority;
                    if (priority != Priority.Idle)
                    {
                        RappelzServer.Instance.SetObjectPriority(this, Priority.Normal);
                    }
                }
            }

            foreach(StateDamage sd in vDamageList)
            {
                Creature caster = Creature.get(sd.caster) as Creature;

                nFlag = 0;

                if(sd.base_effect_id < 11)
                {
                    if (caster == null)
                    {
                        this.RemoveState(sd.uid);
                        continue;
                    }

                    switch(sd.base_effect_id)
                    {
                        case 1:
                            nFlag |= 10;
                            damage = this.DealPhysicalStateDamage(caster, sd.damage_hp, sd.elemental_type, 0, 0, nFlag, this.m_StateStatePenalty, null);
                            break;

                        case 2:
                        case 6:
                            nFlag |= 14;
                            damage = this.DealPhysicalStateDamage(caster, sd.damage_hp, sd.elemental_type, 0, 0, nFlag, this.m_StateStatePenalty, null);
                            break;

                        case 3:
                            nFlag |= 8;
                            damage = this.DealStateMagicalDamage(caster, sd.damage_hp, sd.elemental_type, 0, 0, nFlag, this.m_StateStatePenalty, null);
                            break;

                        case 4:
                            nFlag |= 12;
                            damage = this.DealStateMagicalDamage(caster, sd.damage_hp, sd.elemental_type, 0, 0, nFlag, this.m_StateStatePenalty, null);
                            break;

                        default:
                            continue;
                    }

                    int total_amount = 0;

                    foreach (State st in this.m_vStateList)
                    {
                        if (st.m_nUID == sd.uid )
                        {
                            st.m_nTotalDamage += damage.nDamage;
                            total_amount = st.m_info.id;
                            break;
                        }
                    }

                    pak = new PacketOut(ClientOutPackets.StateResult);

                    pak.WriteUInt32(sd.caster);
                    pak.WriteUInt32(this.m_hHandle);
                    pak.WriteInt32(sd.code);
                    pak.WriteUInt16(sd.level);
                    pak.WriteUInt16(1); // STATE_DAMAGE_HP
                    pak.WriteInt32(damage.nDamage);
                    pak.WriteInt32(this.m_nHP);
                    pak.WriteByte((byte)(sd.final ? 1 : 0));
                    pak.WriteInt32(total_amount);

                    RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),(uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                }
                else
                {
                    nHealHP = 0;
                    nHealMP = 0;

                    switch(sd.base_effect_id)
                    {
                        case 11:
                            nHealHP = this.Heal(sd.damage_hp);
                            break;

                        case 12:
                            nHealMP = (int)this.MPHeal(sd.damage_mp);
                            break;


                        case 21:
                            nHealHP = this.HealByItem(sd.damage_hp);
                            break;

                        case 22:
                            nHealMP = (int)this.MPHealByItem(sd.damage_mp);
                            break;

                        case 24:
                        case 25:
                            nHealHP = this.HealByItem(sd.damage_hp);
                            nHealMP = (int)this.MPHealByItem(sd.damage_mp);
                            break;


                        default:
                            continue;

                    }

                    int total_amount = 0;
                    foreach (State st in this.m_vStateList)
                    {
                        if (st.m_nUID == sd.uid)
                        {
                            int ad = nHealHP;
                            if(ad == 0)
                                ad = nHealMP;
                            if (ad != 0)
                            {
                                st.m_nTotalDamage += ad;
                                total_amount = st.m_nTotalDamage;
                            }
                            break;
                        }
                    }

                    int df = 0;

                    if (nHealHP != 0)
                    {
                        df = nHealHP;
                        pak = new PacketOut(ClientOutPackets.StateResult);

                        pak.WriteUInt32(sd.caster);
                        pak.WriteUInt32(this.m_hHandle);
                        pak.WriteInt32(sd.code);
                        pak.WriteUInt16(sd.level);
                        pak.WriteUInt16(4);
                        pak.WriteInt32(nHealHP);
                        pak.WriteInt32(this.m_nHP);
                        pak.WriteByte((byte)(sd.final ? 1 : 0));
                        pak.WriteInt32(total_amount);
                        RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),(uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                    }

                    if (nHealMP != 0)
                    {
                        df = df != 0 ? -1 : 0;
                        df = total_amount & df;
                        
                        pak = new PacketOut(ClientOutPackets.StateResult);
                        pak.WriteUInt32(sd.caster);
                        pak.WriteUInt32(this.m_hHandle);
                        pak.WriteInt32(sd.code);
                        pak.WriteUInt16(sd.level);
                        pak.WriteUInt16(5);
                        pak.WriteInt32(nHealMP);
                        pak.WriteInt32((int)this.m_fMP);
                        pak.WriteByte((byte)(sd.final ? 1 : 0));
                        pak.WriteInt32(df);
                        RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),(uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                    }
                }
            }

            if (bNeedToProcLightningForceCongestion)
            {
                State lfs = this.GetState(State.StateCode.LightningForceCongestion);

                if (lfs != null)
                {
                    Creature lfsCaster = Creature.get(lfs.m_hCaster[0]) as Creature;
                    damage_hp = (int)(lfs.GetValue(6) + (lfs.GetValue(7) * lfs.GetLevel()));
                    damage_mp = (int)(lfs.GetValue(8) + (lfs.GetValue(9) * lfs.GetLevel()));
                    
                    if (lfsCaster == null || this.m_nHP < (lfs.GetValue(6) + (lfs.GetValue(7) * lfs.GetLevel())) || this.m_fMP < (lfs.GetValue(8) + (lfs.GetValue(9) * lfs.GetLevel())))
                    {
                        this.RemoveState(lfs.m_nUID);
                    }
                    else
                    {
                        byte bbf = (byte)((lfs.m_nLastProcessedTime + 100 * GameContent.GetStateInfo((int)lfs.m_nCode).fire_interval) + (100 * GameContent.GetStateInfo((int)lfs.m_nCode).fire_interval) > lfs.m_nEndTime[0] ? 1 : 0);

                        lfs.m_nLastProcessedTime = (uint)(lfs.m_nLastProcessedTime + 100 * GameContent.GetStateInfo((int)lfs.m_nCode).fire_interval);
                        if (damage_hp != 0)
                        {
                            damage = this.DealDamage(lfsCaster, damage_hp, (Elemental.Type)lfs.m_info.elemental_type,DamageType.StatePhysical,0,0,0,this.m_StateStatePenalty,null);
                            
                            if (damage.nDamage != 0)
                            {
                                pak = new PacketOut(ClientOutPackets.StateResult);
                                lfs.m_nTotalDamage += damage.nDamage;
                                pak.WriteUInt32(lfs.m_hCaster[0]);
                                pak.WriteUInt32(this.m_hHandle);
                                pak.WriteInt32(163420);
                                pak.WriteUInt16(lfs.GetLevel());
                                pak.WriteUInt16(1);
                                pak.WriteInt32(damage.nDamage);
                                pak.WriteInt32(this.m_nHP);
                                pak.WriteByte(bbf);
                                pak.WriteInt32(lfs.m_nTotalDamage);
                                RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),(uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                            }
                        }

                        if (damage_mp != 0)
                        {
                            this.AddMP(-damage_mp);

                            pak = new PacketOut(ClientOutPackets.StateResult);
                            pak.WriteUInt32(lfs.m_hCaster[0]);
                            pak.WriteUInt32(this.m_hHandle);
                            pak.WriteInt32(163420);
                            pak.WriteUInt16(lfs.GetLevel());
                            pak.WriteUInt16(2);
                            pak.WriteInt32(damage_mp);
                            pak.WriteInt32((int)this.m_fMP);
                            pak.WriteByte(bbf);
                            pak.WriteInt32(damage_mp);

                            RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),(uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);

                        }
                    }
                }
            }
        }

        protected virtual void procState(uint t)
        {
//             .text:0043B0DA var_B0          = dword ptr -0B0h
//             .text:0043B0DA var_A8          = dword ptr -0A8h
//             .text:0043B0DA var_9C          = qword ptr -9Ch
//             .text:0043B0DA var_90          = dword ptr -90h
//             .text:0043B0DA add_state_info  = StructCreature::procState::__l2::ADD_STATE_INFO ptr -78h
//             .text:0043B0DA itTarget        = std::_Vector_iterator<StructCreature *,std::allocator<StructCreature *> > ptr -44h
            List<Creature> vTargetList;                                                 // -60  -3Ch
            float fEffectLength;                                                        // -16  -10h
            Creature pCaster;                                                           // 12   0Ch
            int nLevel;                                                                 // 12   0Ch
            List<State> vGoodStateRemover;                                              // 16   10h
            State.StateCode code;                                                       // 52   34h
            Creature pTarget;                                                           // 60   3Ch
            List<int> vGoodStates;                                                      // 64   40h
            int nHitRate;                                                               // 92   5Ch
            bool bHasSequantialStateRemover;                                            // 99   63h
            int i;                                                                      // 100  64h
            int nTargetType;                                                            // 100  64h
//             .text:0043B0DA it              = std::_Vector_iterator<StructState,std::allocator<StructState> > ptr  68h
            uint end_time;                                                              // 112  70h
//             .text:0043B0DA t               = dword ptr  124  7Ch
            List<procStateAddStateInfo> vAddStateInfo;                                  // -36  -24h

// Typedef        :   StructCreature::procState::__l41::lessGoodStateRemover, Type: struct StructCreature::procState::__l41::lessGoodStateRemover
// Typedef        :   StructCreature::procState::__l2::ADD_STATE_INFO, Type: struct StructCreature::procState::__l2::ADD_STATE_INFO
// Data           :   ebp Relative, [00000068], Local, Type: class std::_Vector_iterator<StructState,std::allocator<StructState> >, it
// Data           :   ebp Relative, [FFFFFF88], Local, Type: struct StructCreature::procState::__l2::ADD_STATE_INFO, add_state_info
// Data           :   ebp Relative, [00000050], Local, Type: class std::_Vector_iterator<`StructCreature::procState'::`2'::ADD_STATE_INFO,std::allocator<`StructCreature::procState'::`2'::ADD_STATE_INFO> >, it
 
            vGoodStates = new List<int>();
            vGoodStateRemover = new List<State>();
            vTargetList = new List<Creature>();
            vAddStateInfo = new List<procStateAddStateInfo>();
            bHasSequantialStateRemover = false;
            uint ct = Globals.GetArTime();

            foreach(State st in this.m_vStateList)
            {
                int effect_type = st.GetEffectType();

                if (effect_type == 97)
                {
                    uint lpt = (uint) (st.m_nLastProcessedTime + 100 * st.m_info.fire_interval);
                    if (lpt >= t || lpt > st.m_nEndTime[0])
                        continue;

                    if (st.GetValue(5) == 0.0f)
                        bHasSequantialStateRemover = true;
                    vGoodStateRemover.Add(st);
                }
                else if (!st.IsHarmful())
                {
                    if ((st.GetTimeType() & 1) != 0)
                    {
                        vGoodStates.Add(st.m_nUID);
                    }
                }

                if (effect_type == 88 )
                {
                    if (st.GetValue(1) + st.m_nLastProcessedTime <= ct)
                    {
                        ushort stateLevel = st.GetLevel();
                        code = (State.StateCode)(int)st.GetValue(0);
                        nTargetType = (int)st.GetValue(7);
                        nHitRate = (int)(st.GetValue(8) + (st.GetValue(9) * stateLevel));
                        end_time = (uint)(((st.GetValue(2) + (st.GetValue(3) * stateLevel)) * 100.0f) + ct);

                        if (st.m_hCaster[0] != 0)
                        {
                            pCaster = Creature.get(st.m_hCaster[0]) as Creature;
                            if (pCaster != null)
                            {
                                vTargetList.Clear();
                                GameContent.EnumSkillTargetsAndCalcDamage(this.GetCurrentPosition(ct),this.m_layer,this.GetCurrentPosition(ct),true,
                                    (st.GetValue(4) * 12),-1,0.0f,0,true,pCaster,(int)st.GetValue(5),(int)st.GetValue(6),vTargetList,true);

                                foreach(Creature cr in vTargetList)
                                {
                                    if (cr != null && cr.m_nHP != 0)
                                    {
                                        if (nTargetType == 3 )
                                        {
                                            if (!this.IsEnemy(cr, false))
                                                continue;
                                        }
                                        if (nTargetType == 2 )
                                        {
                                            if (!this.IsAlly(cr))
                                                continue;
                                        }
                                        if (nTargetType != 1 || this.IsAlly(cr) || cr.IsNPC())
                                        {
                                            if (nHitRate >= Globals.GetRandomInt32(0, 99))
                                            {
                                                procStateAddStateInfo nsi = new procStateAddStateInfo();
                                                nsi.code = code;
                                                nsi.nLevel = stateLevel;
                                                nsi.nEndTime = end_time;
                                                nsi.nHate = (int) (st.GetValue(10) + (st.GetValue(11) * stateLevel));
                                                nsi.pTarget = cr;
                                                vAddStateInfo.Add(nsi);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (vGoodStateRemover.Count > 0)
            {
                if (bHasSequantialStateRemover)
                {
//                     *(v2 + 112) = 0;
//                     std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                         (v2 - 44),
//                         *(v2 + 24),
//                         (v2 + 16));
//                     std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                         (v2 + 8),
//                         *(v2 + 20),
//                         (v2 + 16));
//                     v57.baseclass_0._Myptr = *(v2 - 40);
//                     v57.baseclass_0.baseclass_0.baseclass_0._Mycont = *(v2 - 44);
//                     ___sort_V___Vector_iterator_UStructState__V__allocator_UStructState___std___std__UlessGoodStateRemover__CJ___procState_StructCreature__IAEXK_Z__std__YAXV___Vector_iterator_UStructState__V__allocator_UStructState___std___0_0UlessGoodStateRemover__CJ___procState_StructCreature__IAEXK_Z__Z(
//                         *(v2 + 8),
//                         v57,
//                         *(v2 + 112));
//                     std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                         (v2 + 56),
//                         *(v2 + 72),
//                         (v2 + 64));
//                     std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                         v2,
//                         *(v2 + 68),
//                         (v2 + 64));
//                     std::reverse<std::_Vector_iterator<unsigned_int_std::allocator<unsigned_int>>>(*v2, *(v2 + 56));
                }

                foreach (State st in vGoodStateRemover)
                {
                    if(vGoodStates.Count <= 0)
                        break;

                    int stateLevel = st.GetLevel();

                    i = (int)(st.GetValue(0) + (st.GetValue(1) * stateLevel));
                    if (i >  Globals.GetRandomInt32(0, 99))
                        break;

                    if ((int)st.GetValue(5) != 0)
                    {
//                         std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                             (v2 - 92),
//                             *(v2 + 72),
//                             (v2 + 64));
//                         std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                             (v2 + 40),
//                             *(v2 + 68),
//                             (v2 + 64));
//                         v66.baseclass_0._Myptr = *(v2 - 88);
//                         v66.baseclass_0.baseclass_0.baseclass_0._Mycont = *(v2 - 92);
//                         std::random_shuffle<std::_Vector_iterator<int_std::allocator<int>>>(*(v2 + 40), v66);
                    }
                 
                    for (i = 0; i < (st.GetValue(3) + (stateLevel * st.GetValue(4))); ++i)
                    {
                        if(vGoodStates.Count <= 0)
                            break;
                        int sid = vGoodStates.Last();
                        vGoodStates.Remove(sid);
                        this.RemoveState(sid);
                    }
                }
            }

            foreach(procStateAddStateInfo addInfo in vAddStateInfo)
            {
                if (addInfo.pTarget.m_nHP != 0 && addInfo.pTarget.bIsInWorld)
                {
                    addInfo.pTarget.AddState(State.StateType.Normal, addInfo.code, this.m_hHandle, addInfo.nLevel, t, addInfo.nEndTime, false, 0, "");
                    if (addInfo.pTarget.IsMonster())
                    {
                        (addInfo.pTarget as Monster).AddHate(this.m_hHandle, addInfo.nHate,true,true);
                    }
                }
            }
        }

        public int m_nRace;                                 // 0xC4
        public int m_nCriticalCount;                        // 0xC8
        public int m_nHavoc;                                // 0xCC
        public int m_nMaxHavoc;                             // 0xD0
        public int m_nHP;                                   // 0xD4
        public int m_nMaxHP;                                // 0xD8
        public float m_fMaxHPAmplifier;                     // 0xDC
        public int m_nHPDecPart;                            // 0xE0
        public float m_fMP;                                   // 0xE4
        public int m_nMaxMP;                                // 0xE8
        public float m_fMaxMPAmplifier;                     // 0xEC
//        public int m_nMPDecPart;                            // 0xF0
        public int m_nMaxEnergy;                            // 0xF4
        public int m_nEnergy;                               // 0xF8
        public int m_nEnergyStartPos;                       // 0xFC
        public uint[] m_arEnergy = new uint[10];            // 0x100
        public uint m_nEnergyUpkeepTime;                    // 0x128
        public float m_fHealRatio;                          // 0x12C
        public float m_fMPHealRatio;                        // 0x130
        public float m_fHealRatioByItem;                    // 0x134
        public float m_fMPHealRatioByItem;                  // 0x138
        public float m_fHealRatioByRest;                    // 0x13C
        public float m_fMPHealRatioByRest;                  // 0x140
        public int m_nAdditionalHeal;                       // 0x144
        public int m_nAdditionalMPHeal;                     // 0x148
        public int m_nAdditionalHealByItem;                 // 0x14C
        public int m_nAdditionalMPHealByItem;               // 0x150
        public int m_nAdditionalHealByRest;                 // 0x154
        public int m_nAdditionalMPHealByRest;               // 0x158
        public float m_fHateRatio;                          // 0x15C
        public float m_nCastKeep;                           // 0x160
        public int m_nLevel;                                // 0x164
        public int m_nMaxReachedLevel;                      // 0x168
        public float m_fBattleLevel;                        // 0x16C
        public int m_nUnitExpertLevel;                      // 0x170
        public long m_nEXP;                                 // 0x178
        public long m_nLastDecreasedEXP;                    // 0x180
        public int m_nJob;                                  // 0x188
        public int m_nJobLevel;                             // 0x18C
        public int[] m_nPrevJobId = new int[3];             // 0x190
        public int[] m_nPrevJobLevel = new int[3];          // 0x19C
        public long m_nJobPoint;                             // 0x1A8
        public long m_nTotalJobPoint;                        // 0x1AC
        public int m_nRegenHP;                              // 0x1B0
        public float m_fRegenMP;                              // 0x1B4
        public float m_fWeight;                             // 0x1B8
        public CreatureStat m_Stat = new CreatureStat();                         // 0x1BC
        public CreatureStat m_StatByState = new CreatureStat();                  // 0x1CC
// 
        public CreatureAttributeServer m_Attribute = new CreatureAttributeServer();         // 0x1DC
        public CreatureAttributeServer m_AttributeByState = new CreatureAttributeServer();  // 0x220
        public CreatureElementalResist m_Resist = new CreatureElementalResist();            // 0x264
        public CreatureStatAmplifier m_StatAmplifier = new CreatureStatAmplifier();         // 0x272
        public CreatureAttributeAmplifier m_AttributeAmplifier = new CreatureAttributeAmplifier();              // 0x2B2
        public CreatureElementalResistAmplifier m_ResistAmplifier = new CreatureElementalResistAmplifier();     // 0x3C2
        public float m_nAttackPointRightWithoutWeapon;      // 0x3FA
        public float m_nAttackPointLeftWithoutWeapon;       // 0x3FC
        public float m_fBowInterval;                        // 0x400
        public StatusFlags m_StatusFlag;                                    // 0x404
        public bool m_bNeedToBroadcastStatusFlag;                   // 0x408
        public Item[] m_anWear = new Item[24];                      // 0x40C
        public float m_fHPRegenMod;                                 // 0x46C
        public float m_fMPRegenMod;                                 // 0x470
        public float m_fItemMod;                                    // 0x474
        public uint m_nMovableTime;                                 // 0x478
        public uint m_nLastUpdateTime;                              // 0x47C
        public uint m_nNextAttackableTime;                          // 0x480
        public uint m_nLastHavocUpdateTime;                         // 0x484
        public uint m_nLastStateProcTime;                           // 0x488
        public uint m_nDeadTime;                                    // 0x48C

        protected void broadcastAttackMessage(Creature pTarget, Creature.AttackInfo[] arDamage, int tm, int delay, bool bIsDoubleAttack, bool bIsAiming, bool bEndAttack, bool bCancelAttack)
        {
            AttackEventPacketSC packet = new AttackEventPacketSC();

            int attack_count = 1;
            if (bEndAttack || bCancelAttack)
                attack_count = 0;

            if ((this.m_StatusFlag & StatusFlags.FormChanged) == 0)
            {
                if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    attack_count *= 2;
                if ( bIsDoubleAttack )
                    attack_count *= 2;
            }

            packet.attack_flag = 0;

            if ((this.m_StatusFlag & StatusFlags.FormChanged) == 0)
            {
                if (bIsDoubleAttack)
                    packet.attack_flag = (byte)AttackEventPacketSC.AttackFlag.DoubleAttack;
                if ((this.m_StatusFlag & StatusFlags.UsingDoubleWeapon) != 0)
                    packet.attack_flag |= (byte)AttackEventPacketSC.AttackFlag.DoubleWeapon;
                if (this.IsUsingBow() && this.IsPlayer())
                    packet.attack_flag |= (byte)AttackEventPacketSC.AttackFlag.Bow;
                if (this.IsUsingCrossBow() && this.IsPlayer())
                    packet.attack_flag |= (byte)AttackEventPacketSC.AttackFlag.CrossBow;
            }

            packet.attack_action = (byte)AttackEventPacketSC.AttackAction.Attack;
            if (bIsAiming)
            {
                packet.attack_action = (byte)AttackEventPacketSC.AttackAction.Aiming;
            }
            else if (bEndAttack)
            {
                packet.attack_action = (byte)AttackEventPacketSC.AttackAction.End;
            }
            else if (bCancelAttack)
            {
                packet.attack_action = (byte)AttackEventPacketSC.AttackAction.Cancel;
            }

            packet.attack_speed = (ushort) tm;
            packet.attack_delay = (ushort) delay;

            packet.count = (byte) attack_count;
            packet.attacker_handle = this.m_hHandle;
            if (pTarget != null)
                packet.target_handle = pTarget.m_hHandle;
            else
                packet.target_handle = 0;

            for (int i = 0; i < attack_count; ++i)
            {
                AttackEventPacketSC.AttackInfo info = new AttackEventPacketSC.AttackInfo();

                info.damage = arDamage[i].nDamage;
                info.mp_damage = arDamage[i].mp_damage;
                info.attacker_damage = arDamage[i].attacker_damage;
                info.attacker_mp_damage = arDamage[i].attacker_mp_damage;
                info.target_hp = (uint) arDamage[i].target_hp;
                info.target_mp = arDamage[i].target_mp;
                info.attacker_hp = arDamage[i].attacker_hp;
                info.attacker_mp = arDamage[i].attacker_mp;
                info.flag = 0;
                if (arDamage[i].bPerfectBlock)
                    info.flag = (byte)AttackEventPacketSC.Flag.PerfectBlock;
                if (arDamage[i].bBlock)
                    info.flag |= (byte)AttackEventPacketSC.Flag.Block;
                if (arDamage[i].bMiss)
                    info.flag |= (byte)AttackEventPacketSC.Flag.Miss;
                if (arDamage[i].bCritical)
                    info.flag |= (byte)AttackEventPacketSC.Flag.Critical;
                info.elemental_damage[0] = arDamage[i].elemental_damage[0];
                info.elemental_damage[1] = arDamage[i].elemental_damage[1];
                info.elemental_damage[2] = arDamage[i].elemental_damage[2];
                info.elemental_damage[3] = arDamage[i].elemental_damage[3];
                info.elemental_damage[4] = arDamage[i].elemental_damage[4];
                info.elemental_damage[5] = arDamage[i].elemental_damage[5];
                info.elemental_damage[6] = arDamage[i].elemental_damage[6];
                packet.v_Info.Add(info);
            }

            PacketOut po = new PacketOut((ushort)ClientOutPackets.AttackEvent);
            packet.WriteToPacket(po);
            RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize), (uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, po);
        }


        protected virtual void onAttackAndSkillProcess()
        {
            if (this.m_pCastSkill != null)
            {
                this.processSkill();
            }
            else
            {
                if (this.m_hEnemy != 0)
                    this.processAttack();
            }
        }

        public uint m_hEnemy;                                       // 0x490
// Data           :   this+0x494, Member, Type: class XCriticalSection, m_csEnemy
// UserDefinedType:     XCriticalSection
// 
        public List<uint> m_vEnemyList = new List<uint>();          // 0x4D4
        public int m_nElementalEffectAttackPointRight;              // 0x4E4
        public int m_nElementalEffectAttackPointLeft;               // 0x4E8
        public int m_nElementalEffectMagicPoint;                    // 0x4EC
// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0x0, Constant, Type: int, AM_ATTACK
// Data           :     constant 0x1, Constant, Type: int, AM_AIMING
        public int m_nNextAttackMode;                               // 0x4F0
        public List<ArPosition> m_PendingMovePos = new List<ArPosition>();  // 0x4F4
        public byte m_nPendingMoveSpeed;                            // 0x504
        public float m_fDetectHideRange;                            // 0x508
        public float m_fCreatureCardChance;                         // 0x50C
        public List<uint> m_vAimerList = new List<uint>();          // 0x510
        public ushort m_nCurrentStateUID;                                                       // 0x520
        public List<State> m_vStateList = new List<State>();                                    // 0x524 
        public List<State> m_vStateListRemovedByDeath = new List<State>();                      // 0x534
        public int m_nPendedClearStateFlag;                                                     // 0x544
        public float m_fResistHarmfulState;                                                     // 0x548


        public List<AddStateTag> m_vStateByNormalAttack = new List<AddStateTag>();          // 0x54C
        public List<DamageAbsorbTag> m_vAbsorbByNormalAttack = new List<DamageAbsorbTag>(); // 0x55C
        public List<HealOnAttackTag> m_vHealOnAttack = new List<HealOnAttackTag>();         // 0x56C
        public List<StealOnAttackTag> m_vStealOnAttack = new List<StealOnAttackTag>();      // 0x57C
        public int m_nDoubleWeaponMasteryLevel;                                             // 0x58C
        public ExpertMod[] m_Expert = new ExpertMod[10];                                    // 0x590
        public StateMod m_NormalStateAdvantage = new StateMod();                            // 0x5E0
        public StateMod m_RangeStateAdvantage = new StateMod();                             // 0x5F4
        public StateMod m_NormalStatePenalty = new StateMod();                              // 0x608
        public StateMod m_RangeStatePenalty = new StateMod();                               // 0x61C
        public StateMod m_PhysicalSkillStatePenalty = new StateMod();                       // 0x630
        public StateMod m_MagicalSkillStatePenalty = new StateMod();                        // 0x644
        public StateMod m_StateStatePenalty = new StateMod();                               // 0x658
        public ElementalSkillStateMod[] m_GoodPhysicalElementalSkillStateMod = new ElementalSkillStateMod[7];   // 0x66C
        public ElementalSkillStateMod[] m_BadPhysicalElementalSkillStateMod = new ElementalSkillStateMod[7];   // 0x880
        public ElementalSkillStateMod[] m_GoodMagicalElementalSkillStateMod = new ElementalSkillStateMod[7];   // 0xA94
        public ElementalSkillStateMod[] m_BadMagicalElementalSkillStateMod = new ElementalSkillStateMod[7];   // 0xCA8

// Function       :   protected void StructCreature::removeExhaustiveSkillStateMod(struct StructCreature::ElementalSkillStateMod *, unsigned long)

        public List<HateModifier> m_vHateMod = new List<HateModifier>();            // 0xEBC

        public List<AdditionalDamageInfo> m_vNormalAdditionalDamage = new List<AdditionalDamageInfo>();                     // 0xECC
        public List<AdditionalDamageInfo> m_vRangeAdditionalDamage = new List<AdditionalDamageInfo>();                      // 0xEDC
        public List<AdditionalDamageInfo> m_vPhysicalSkillAdditionalDamage = new List<AdditionalDamageInfo>();              // 0xEEC
        public List<AdditionalDamageInfo> m_vMagicalSkillAdditionalDamage = new List<AdditionalDamageInfo>();               // 0xEFC

        public List<DamageReflectInfo> m_vDamageReflectInfo = new List<DamageReflectInfo>();                                // 0xF0C
        public List<StateReflectInfo> m_vStateReflectInfo = new List<StateReflectInfo>();                                   // 0xF1C
        public List<DamageReduceInfo> m_vDamageReducePercentInfo = new List<DamageReduceInfo>();                            // 0xF2C
        public List<DamageReduceInfo> m_vDamageReduceValueInfo = new List<DamageReduceInfo>();                              // 0xF3C
        public List<AddHPMPOnCriticalInfo> m_vAddHPMPOnCritical = new List<AddHPMPOnCriticalInfo>();                        // 0xF4C

        public List<int> m_vInterruptedSkill = new List<int>();                         // 0xF5C 
        public float m_fPhysicalDamageManaShieldAbsorbRatio;                            // 0xF6C
        public float m_fMagicalDamageManaShieldAbsorbRatio;                             // 0xF70
        public Skill m_pCastSkill;                                                      // 0xF74
        public List<Skill> m_vAllSkillList = new List<Skill>();                         // 0xF78
        public List<Skill> m_vPassiveSkillList = new List<Skill>();                     // 0xF88
        public List<Skill> m_vAmplifyPassiveSkillList = new List<Skill>();              // 0xF98
        public List<Skill> m_vActiveSkillList = new List<Skill>();                      // 0xFA8

// Function       :   protected struct StructSkill * StructCreature::getSkill(int)
        
        public uint m_hSkillTarget;                                                     // 0xFB8

        public List<RappelzPair<int, Skill>> m_vAura = new List<RappelzPair<int, Skill>>(); // 0xFBC 
        public uint m_hTrap;                                                            // 0xFCC
        public List<SetItemEffectInfo> m_vSetItemEffect = new List<SetItemEffectInfo>();    // 0xFD0
// 
// Function       :   public struct StructCreature & operator=(const struct StructCreature &)

    }
}
